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

whistle 如何支持自动化测试,有哪些测试框架集成方案?

2月21日 16:25

答案

Whistle 支持自动化测试,可以与各种测试框架集成,提高测试效率和质量。

自动化测试基础

1. 测试环境配置

安装测试依赖:

bash
npm install --save-dev whistle puppeteer jest

配置测试环境:

javascript
// setup-whistle.js const { spawn } = require('child_process'); let whistleProcess; beforeAll(async () => { // 启动 whistle whistleProcess = spawn('w2', ['start', '-p', '8899']); // 等待 whistle 启动 await new Promise(resolve => setTimeout(resolve, 3000)); }); afterAll(async () => { // 停止 whistle spawn('w2', ['stop']); // 等待 whistle 停止 await new Promise(resolve => setTimeout(resolve, 1000)); });

Jest 集成

1. 基本测试用例

创建测试文件: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 () => { // 配置 whistle 规则 const rules = 'www.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // 访问测试页面 await page.goto('http://www.example.com'); // 验证请求被代理 const response = await page.goto('http://www.example.com'); expect(response.status()).toBe(200); }); test('should mock API responses', async () => { // 配置 mock 规则 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); // 访问 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. 高级测试用例

测试跨域处理:

javascript
test('should handle CORS correctly', async () => { // 配置 CORS 规则 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); // 测试跨域请求 const response = await page.evaluate(async () => { const res = await fetch('http://www.example.com/api/data'); return res.json(); }); expect(response).toBeDefined(); });

测试 HTTPS 拦截:

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

Cypress 集成

1. 配置 Cypress

创建配置文件:cypress.config.js

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

2. 创建测试用例

创建测试文件:cypress/e2e/whistle.cy.js

javascript
describe('Whistle E2E Tests', () => { beforeEach(() => { // 配置 whistle 规则 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. 配置 Cypress 任务

创建任务文件: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 集成

1. 配置 Playwright

创建配置文件:playwright.config.js

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

2. 创建测试用例

创建测试文件: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 () => { // 配置 whistle 规则 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'); }); });

性能测试

1. 使用 Lighthouse

创建性能测试:

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. 使用 WebPageTest

创建性能测试脚本:

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 测试

1. 使用 Supertest

创建 API 测试:

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 () => { // 配置 whistle 规则 const rules = 'api.example.com host 127.0.0.1:3000'; fs.writeFileSync(path.join(__dirname, 'test.rules'), rules); // 测试 API 请求 const response = await request(app) .get('/api/test') .set('Host', 'api.example.com') .expect(200); expect(response.body.message).toBe('success'); });

2. 使用 Axios

创建 API 测试:

javascript
const axios = require('axios'); test('should handle API responses correctly', async () => { // 配置 whistle 规则 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); // 测试 API 请求 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 集成

1. GitHub Actions

创建工作流文件:.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

创建 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' } } } }

最佳实践

  1. 隔离测试环境

    • 使用独立的测试端口
    • 配置独立的规则文件
    • 避免测试互相干扰
  2. 清理测试资源

    • 测试后清理规则文件
    • 停止 whistle 进程
    • 清理临时文件
  3. 使用 Mock 数据

    • 使用固定的 Mock 数据
    • 避免依赖外部服务
    • 提高测试稳定性
  4. 并行测试

    • 使用不同的端口
    • 配置独立的 whistle 实例
    • 提高测试效率
  5. 监控测试结果

    • 记录测试日志
    • 分析失败原因
    • 持续优化测试
标签:Whistle