Vue SPA集成测试:WebdriverIO+CucumberJS环境下Stub API请求方案咨询
我之前在做Vue SPA的WebdriverIO+Cucumber集成测试时,刚好碰到过和你一模一样的需求——不想改源码URL,还要拦截API请求返回自定义数据。Nock这类工具因为是在Node环境生效,而Selenium加载的应用是在浏览器环境,确实用不了。给你几个基于WebdriverIO本身的可行方案,亲测好用:
方案1:WebdriverIO内置Mock功能(推荐,适用于v7+版本)
WebdriverIO从v7开始内置了网络请求Mock功能,底层基于Chrome DevTools Protocol(CDP)实现,不用额外装依赖,代码也非常简洁。
在你的Cucumber步骤定义里可以这么写:
Given('the app loads with mocked API data', async () => { // 创建Mock,匹配目标API的URL(支持通配符,比如`https://your-api.com/*`) const apiMock = await browser.mock('https://your-api-domain.com/target-endpoint'); // 设置自定义响应内容、状态码和响应头 apiMock.respond( { // 这里放你的自定义JSON数据 items: [ { id: 1, name: 'Mocked Item 1' }, { id: 2, name: 'Mocked Item 2' } ] }, { statusCode: 200, headers: { 'Content-Type': 'application/json' } } ); // 加载你的Vue SPA应用 await browser.url('/'); });
测试完成后,记得在After钩子中清理Mock,避免影响其他测试用例:
After(async () => { await browser.mockRestore(); });
这个方案的优势是官方维护、API简洁,还支持多种匹配规则(比如按请求方法、请求头匹配),完全不用修改源码里的API地址。
方案2:直接调用Chrome DevTools Protocol(CDP)
如果你的WebdriverIO版本较低,或者需要更灵活的拦截逻辑(比如动态修改响应、拦截特定阶段的请求),可以直接调用CDP的Network接口来实现拦截。
示例代码如下:
Given('the API request is intercepted with custom data', async () => { // 启用CDP的Network模块 await browser.cdp('Network', 'enable'); // 设置请求拦截规则,匹配目标API的URL和资源类型 await browser.cdp('Network', 'setRequestInterception', { patterns: [ { urlPattern: 'https://your-api-domain.com/target-endpoint', resourceType: 'XHR', // 只拦截XHR请求,也可以用'Fetch' interceptionStage: 'HeadersReceived' } ] }); // 监听拦截事件,返回自定义响应 browser.on('Network.requestIntercepted', async (event) => { // 将自定义JSON转为Base64编码(CDP要求响应体用Base64) const mockResponseBody = Buffer.from(JSON.stringify({ items: [{ id: 1, name: 'Custom Mocked Data' }] })).toString('base64'); await browser.cdp('Network', 'continueInterceptedRequest', { interceptionId: event.interceptionId, responseCode: 200, responseHeaders: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' // 解决跨域问题(如果需要) }, body: mockResponseBody }); }); // 加载应用 await browser.url('/'); });
测试结束后记得关闭Network模块:
After(async () => { await browser.cdp('Network', 'disable'); // 移除事件监听,避免内存泄漏 browser.removeAllListeners('Network.requestIntercepted'); });
注意事项
- 这两个方案都要求你的测试浏览器支持CDP,比如Chrome、Edge、Firefox(版本>=75),Safari目前对CDP的支持有限,可能需要调整。
- 对于Vue SPA,建议在拦截设置完成后再加载应用,确保请求被正确拦截。
- 如果需要拦截多个API请求,可以在同一个步骤里创建多个Mock,或者扩展CDP的拦截规则。
内容的提问来源于stack exchange,提问作者Alex Smolov
相关产品推荐
相关产品推荐

