乐闻世界logo
搜索文章和话题

How does whistle support automated testing and what are testing framework integration solutions?

2月21日 16:25

Answer

Whistle supports automated testing and can integrate with various testing frameworks to improve testing efficiency and quality.

Automated Testing Basics

1. Test Environment Configuration

Install test dependencies:

bash
npm install --save-dev whistle puppeteer jest

Configure test environment:

javascript
// setup-whistle.js const { spawn } = require('child_process'); let whistleProcess; beforeAll(async () => { // Start whistle whistleProcess = spawn('w2', ['start', '-p', '8899']); // Wait for whistle to start await new Promise(resolve => setTimeout(resolve, 3000)); }); afterAll(async () => { // Stop whistle spawn('w2', ['stop']); // Wait for whistle to stop await new Promise(resolve => setTimeout(resolve, 1000)); });

Jest Integration

1. Basic Test Cases

Create test file: whistle.test.js

javascript
const puppeteer = require('puppeteer'); const fs = require('fs'); const path = require('path'); describe('Whistle Tests', () => { let browser; let page; beforeAll(async () => { browser = await puppeteer.launch({ args: ['--proxy-server=127.0.0.1:8899'] }); page = await browser.newPage(); }); afterAll(async () => { await browser.close(); }); test('should proxy requests correctly', async () => { // Configure whistle rules const rules = 'www.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Visit test page await page.goto('http://www.example.com'); // Verify request is proxied const response = await page.goto('http://www.example.com'); expect(response.status()).toBe(200); }); test('should mock API responses', async () => { // Configure mock rules const mockData = JSON.stringify({ code: 0, data: 'mock' }); const rules = `www.example.com/api/user resBody://${mockData}`; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Visit API const response = await page.goto('http://www.example.com/api/user'); const data = await response.json(); expect(data.code).toBe(0); expect(data.data).toBe('mock'); }); });

2. Advanced Test Cases

Test CORS handling:

javascript
test('should handle CORS correctly', async () => { // Configure CORS rules const corsHeaders = JSON.stringify({ 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS' }); const rules = `www.example.com resHeaders://${corsHeaders}`; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Test cross-origin request const response = await page.evaluate(async () => { const res = await fetch('http://www.example.com/api/data'); return res.json(); }); expect(response).toBeDefined(); });

Test HTTPS interception:

javascript
test('should intercept HTTPS requests', async () => { // Configure HTTPS rules const rules = 'https://www.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Visit HTTPS page const response = await page.goto('https://www.example.com'); expect(response.status()).toBe(200); });

Cypress Integration

1. Configure Cypress

Create config file: cypress.config.js

javascript
const { defineConfig } = require('cypress'); module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { // Configure browser proxy on('before:browser:launch', (browser, launchOptions) => { launchOptions.args.push(`--proxy-server=http://127.0.0.1:8899`); return launchOptions; }); }, }, });

2. Create Test Cases

Create test file: cypress/e2e/whistle.cy.js

javascript
describe('Whistle E2E Tests', () => { beforeEach(() => { // Configure whistle rules cy.task('setWhistleRules', 'www.example.com host 127.0.0.1:3000'); }); it('should proxy requests correctly', () => { cy.visit('http://www.example.com'); cy.contains('Example Domain').should('be.visible'); }); it('should mock API responses', () => { const mockData = { code: 0, data: 'mock' }; cy.task('setWhistleRules', `www.example.com/api/user resBody://${JSON.stringify(mockData)}`); cy.request('http://www.example.com/api/user').then((response) => { expect(response.body.code).to.equal(0); expect(response.body.data).to.equal('mock'); }); }); });

3. Configure Cypress Tasks

Create task file: cypress/plugins/index.js

javascript
const fs = require('fs'); const path = require('path'); module.exports = (on, config) => { on('task', { setWhistleRules(rules) { const rulesPath = path.join(__dirname, '../../test.rules'); fs.writeFileSync(rulesPath, rules); return null; }, }); };

Playwright Integration

1. Configure Playwright

Create config file: playwright.config.js

javascript
const { defineConfig, devices } = require('@playwright/test'); module.exports = defineConfig({ use: { proxy: { server: 'http://127.0.0.1:8899', }, }, });

2. Create Test Cases

Create test file: whistle.spec.js

javascript
const { test, expect } = require('@playwright/test'); const fs = require('fs'); const path = require('path'); test.describe('Whistle Playwright Tests', () => { test.beforeEach(async () => { // Configure whistle rules const rules = 'www.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); }); test('should proxy requests correctly', async ({ page }) => { await page.goto('http://www.example.com'); const title = await page.title(); expect(title).toContain('Example Domain'); }); test('should mock API responses', async ({ page, request }) => { const mockData = { code: 0, data: 'mock' }; const rules = `www.example.com/api/user resBody://${JSON.stringify(mockData)}`; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); const response = await request.get('http://www.example.com/api/user'); const data = await response.json(); expect(data.code).toBe(0); expect(data.data).toBe('mock'); }); });

Performance Testing

1. Use Lighthouse

Create performance test:

javascript
const lighthouse = require('lighthouse'); const chromeLauncher = require('chrome-launcher'); test('should meet performance standards', async () => { const chrome = await chromeLauncher.launch({ chromeFlags: ['--proxy-server=127.0.0.1:8899'] }); const options = { logLevel: 'info', output: 'json', port: chrome.port }; const runnerResult = await lighthouse('http://www.example.com', options); const metrics = runnerResult.lhr.audits; expect(metrics['first-contentful-paint'].numericValue).toBeLessThan(2000); expect(metrics['interactive'].numericValue).toBeLessThan(5000); await chrome.kill(); });

2. Use WebPageTest

Create performance test script:

javascript
const WebPageTest = require('webpagetest'); test('should meet WebPageTest standards', async () => { const wpt = new WebPageTest('www.webpagetest.org', 'YOUR_API_KEY'); const result = await wpt.runTest('http://www.example.com', { location: 'Dulles:Chrome', firstViewOnly: true, proxy: '127.0.0.1:8899' }); const data = result.data; expect(data.average.firstView.TTFB).toBeLessThan(500); expect(data.average.firstView.loadTime).toBeLessThan(3000); });

API Testing

1. Use Supertest

Create API test:

javascript
const request = require('supertest'); const express = require('express'); const app = express(); app.get('/api/test', (req, res) => { res.json({ message: 'success' }); }); test('should proxy API requests correctly', async () => { // Configure whistle rules const rules = 'api.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Test API request const response = await request(app) .get('/api/test') .set('Host', 'api.example.com') .expect(200); expect(response.body.message).toBe('success'); });

2. Use Axios

Create API test:

javascript
const axios = require('axios'); test('should handle API responses correctly', async () => { // Configure whistle rules const mockData = { code: 0, data: 'test' }; const rules = `api.example.com/api/test resBody://${JSON.stringify(mockData)}`; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // Test API request const response = await axios.get('http://api.example.com/api/test'); expect(response.data.code).toBe(0); expect(response.data.data).toBe('test'); });

CI/CD Integration

1. GitHub Actions

Create workflow file: .github/workflows/test.yml

yaml
name: Test on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm install - name: Install whistle run: npm install -g whistle - name: Start whistle run: w2 start -p 8899 - name: Run tests run: npm test - name: Stop whistle run: w2 stop

2. Jenkins Pipeline

Create Jenkinsfile:

groovy
pipeline { agent any stages { stage('Setup') { steps { sh 'npm install' sh 'npm install -g whistle' sh 'w2 start -p 8899' } } stage('Test') { steps { sh 'npm test' } } stage('Cleanup') { steps { sh 'w2 stop' } } } }

Best Practices

  1. Isolate Test Environment

    • Use independent test ports
    • Configure independent rule files
    • Avoid test interference
  2. Clean Up Test Resources

    • Clean up rule files after tests
    • Stop whistle processes
    • Clean up temporary files
  3. Use Mock Data

    • Use fixed mock data
    • Avoid dependency on external services
    • Improve test stability
  4. Parallel Testing

    • Use different ports
    • Configure independent whistle instances
    • Improve test efficiency
  5. Monitor Test Results

    • Record test logs
    • Analyze failure reasons
    • Continuously optimize tests
标签:Whistle