5月30日 22:48

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

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