如何使用木偶师测试异常行为?



许多人都有使用Puppeteer进行通用自动化测试的经验。这主要是关于模仿网页上的用户行为并断言结果。但是,如果您需要测试错误状态的表示形式,而您无法(或不知道如何(由用户操作触发,该怎么办?例如,我们有一个表单。当用户提交时,应用会向服务器发送 POST 请求,并在服务器响应 200 OK 后立即显示成功消息。这是预期的行为。然而,在现实世界中,服务器可能碰巧关闭或响应内部错误。想象一下,该应用程序感激地涵盖了这种情况。但是我们如何用木偶师重现它呢?

鉴于Puppeteer在处理HTTP/S请求方面提供了很多可能性,我想出了以下解决方案。 在提交表单时,我用自己的表单模拟服务器响应。 基本上,我设置了一个拦截器,它将与给定 URL 片段匹配的下一个请求替换为自定义服务器响应:

await bs.mockRequest( "response.json", { "GET", "500 Internal Server Error", "application/javascript", "{ "status": "FAIL" }", [] });

当它监视网络时,我可以提交表单,例如通过模拟单击提交按钮。以下请求将被替换,以便受测应用将其视为实际服务器错误的情况。

这里是 mockRequest 的源代码:

class BrowserSession {
// obtaining page context from Puppeteer
// @see https://pptr.dev/#?product=Puppeteer&version=v2.0.0&show=api-puppeteerlaunchoptions
async setup( options ) {
this.browser = await puppeteer.launch( options );
this.context = await this.browser.createIncognitoBrowserContext();
this.page = await this.context.newPage();
}
/**
* Intercept and replace request
* @param {String} url - URL substring to match
* @param {Object} newRespond 
*/
async mockRequest( url, { method, status, contentType, newBody, headers }) {
const session = await this.page.target().createCDPSession(),
patterns = [ `*${ url }*` ];
await session.send( "Network.enable" );
await session.send( "Network.setRequestInterception", {
patterns: patterns.map( pattern => ({
urlPattern: pattern,
interceptionStage: "HeadersReceived"
}))
});
session.on( "Network.requestIntercepted", async ({ interceptionId, request, responseHeaders, resourceType }) => {
if ( ( method || "GET" ) !== request.method.toUpperCase() ) {
await session.send( "Network.continueInterceptedRequest", { interceptionId });
return;
}
const newHeaders = [
"Date: " + ( new Date() ).toUTCString(),
"Connection: closed",
"Content-Length: " + newBody.length,
"Content-Type: " + contentType,
...headers
];
await session.send( "Network.continueInterceptedRequest", {
interceptionId,
rawResponse: btoa( `HTTP/1.1 ${ status }rn`
+ newHeaders.join('rn') + 'rnrn' + newBody )
});
session.detach();
});
}
}

最新更新