whistle 如何接入自动化测试并稳定 Mock 网络请求?
Whistle 可以接入自动化测试,但它更适合作为“可控网络层”,而不是替代测试框架。Jest、Playwright、Puppeteer 负责断言和驱动浏览器,whistle 负责代理、Mock 和改包。这样测试代码不用侵入业务接口,也能复现弱网、跨域和接口异常。边界也要说清楚:如果只是单元测试,直接 mock 函数更轻;只有涉及浏览器真实网络、HTTPS 或 WebSocket 时,whistle 的价值才明显。
先把 whistle 作为测试前置服务启动,端口固定,避免 CI 和本机不一致。
bashnpm i -D jest puppeteer npm i -g whistle w2 start -p 8899 w2 stop
浏览器侧只需要把代理指向 whistle。Puppeteer 的配置通常放在测试 setup 里,Playwright 也有类似的 proxy 选项。
jsconst browser = await puppeteer.launch({ headless: 'new', args: ['--proxy-server=http://127.0.0.1:8899'] })
Mock 规则建议单独维护,不要散落在测试用例里。比如把线上 API 改到本地服务,或者直接返回固定 JSON:
txtapi.example.com host 127.0.0.1:3000 https://api.example.com/user resBody://{"code":0,"name":"mock-user"} https://api.example.com/user resHeaders://{"content-type":"application/json"}
在 CI 里要额外处理两个细节:第一,等待 whistle 真正启动后再跑测试,不能只 sleep 一秒就赌运气;第二,HTTPS 场景需要提前安装并信任 whistle 根证书。测试环境可临时加 ignoreHTTPSErrors,但它会掩盖证书链问题,不适合验证支付、登录链路。
追问
Jest、Playwright 和 Puppeteer 该选哪个?
如果测试重点是函数和组件逻辑,Jest 足够,没必要引入 whistle。只要验证真实页面请求、跳转、Cookie 或跨域行为,就应该用 Playwright 或 Puppeteer 驱动浏览器,再让 whistle 接管网络。Playwright 在多浏览器和等待机制上更省心,Puppeteer 更贴近 Chrome 调试。取舍点是维护成本:端到端测试越真实,运行越慢,也越容易受环境影响。
Mock 数据应该写在 whistle 规则里还是测试代码里?
稳定的接口替身适合写成 whistle 规则,因为规则可以被开发、测试和 CI 复用。和断言强相关的一次性数据,可以放在测试代码里,避免规则文件变成没人敢改的“黑盒”。踩坑最多的是两边都写,最后不知道哪个 Mock 生效。建议给规则文件加命名约定,例如 e2e-login.rules。
HTTPS 自动化测试为什么经常失败?
最常见原因是证书没有被系统或浏览器信任,whistle 能看到请求,但页面侧直接阻断。另一个坑是某些客户端启用了证书固定,代理解密会失败,这类场景只能做旁路抓包或在测试包关闭 pinning。CI 容器里还要注意证书安装路径,不同镜像的信任库不一样。不要把 ignoreHTTPSErrors 当万能药,它只能让浏览器继续跑,不能证明 HTTPS 链路真的没问题。
如何判断 whistle 规则真的被测试用例命中了?
不要只看页面断言通过,还要检查网络侧是否经过预期域名和规则。可以在 whistle 界面查看请求,也可以让被 Mock 的响应返回测试专用字段,例如 x-mock-source: whistle-e2e。如果接口被浏览器缓存,规则可能根本没走,所以测试前最好禁用缓存或给请求加唯一 query。定位失败时先验证代理配置,再验证规则匹配,最后看业务断言。
什么时候不该把 whistle 放进自动化测试?
纯算法、纯组件渲染和后端接口契约测试,不需要 whistle,直接 mock 或启动本地服务更快。whistle 适合解决“网络路径不可控”的问题,不适合承担所有测试隔离职责。规则过多会让测试变慢,也会让新人很难理解真实请求链路。一个实用边界是:只有当问题必须在浏览器代理层复现时,才把它纳入 whistle 自动化测试。