网络测试指南¶
本文档旨在介绍 necko 中使用的不同测试类型。目标读者是 necko 团队的新成员。
Necko 测试类型¶
本节仅介绍 netwerk/test 文件夹下的测试。
-
当要测试的代码需要浏览器窗口来加载某些特定资源时,我们通常会编写 Chrome 测试。
-
在 necko 中很少使用。
-
当要测试的代码可以通过 WebIDL 触发时使用。例如,WebSocket 和 XMLHttpRequest。
-
主要用于 necko 测试可以通过 JS 访问的对象。例如,
nsIHttpChannel
。
-
在不需要 HTTP 服务器时很有用。
在编写与解析字符串相关的代码时很有用。例如,解析 Server Timing Header
-
当前 netwerk/test/perf 中的所有测试都用于测试
HTTP/3
代码。
还有一些与 necko 相关的 web-platform-tests。我们通常不会编写新的 web-platform-tests
。但是,我们确实有很多用于 XHR、Fetch 和 WebSocket 的 web-platform-tests
。
运行 Necko xpcshell-tests¶
本地
运行所有 xpcshell-tests
./mach xpcshell-test netwerk/test/unit
请注意,xpcshell-tests 是并行运行的,有时为了调试,我们希望按顺序运行它们。
./mach xpcshell-test --sequential netwerk/test/unit
运行单个测试
./mach xpcshell-test netwerk/test/unit/test_http3.js
启用套接字进程运行
./mach xpcshell-test --setpref="network.http.network_access_on_socket_process.enabled=true" netwerk/test/unit/test_http3.js
我们通常使用
HTTP Logging
调试网络问题。要在运行测试时启用日志记录MOZ_LOG=nsHttp:5 ./mach xpcshell-test netwerk/test/unit/test_http3.js
远程
首先,我们需要了解 模糊选择器,这是我们用于选择在 try 上运行哪些测试的工具。如果您已经知道您的代码更改可以通过 necko xpcshell-tests 覆盖,您可以使用以下命令在 try 上运行
netwerk/test/unit
中的所有测试。./mach try fuzzy netwerk/test/unit
在 try 上运行单个测试
./mach try fuzzy netwerk/test/unit/test_http3.js
有时我们希望在启用日志记录的情况下调试 try 上失败的测试
./mach try fuzzy --env "MOZ_LOG=nsHttp:5,nsHostResolver:5" netwerk/tesst/unit/test_http3.js
请注意,在 try 上运行文件夹中的所有测试时启用日志记录通常不是一个好主意,因为原始日志文件可能非常大。如果文件大小超过 try 上的限制,则日志文件可能不可用。如果您代码更改过于通用或不确定要运行哪些测试,则可以使用 自动选择器 让它为您选择测试。
调试间歇性测试失败¶
try 上有很多间歇性故障(通常无法在本地重现)。调试这些故障可能非常烦人和耗时。以下是一些帮助您更有效地调试间歇性故障的一般准则。
确定故障是否由您的代码更改引起。
尝试在本地重现间歇性故障。这是最直接的方法。在本地调试时添加
--verify
标志也很有用(有关更多详细信息,请参阅此 文档)。我们可以检查 try 上的故障摘要,看看此测试故障是否已提交 Bug。如果是,则很可能这不是由您的代码更改引起的。
重新触发失败的测试几次,看看它是否通过。这可以通过单击
Push Health
按钮轻松完成。查找当前其他提交中发生的类似故障。这可以通过以下方式完成
click on failing job -> read failure summary -> find similar ones by other authors in similar jobs
要重新运行失败的测试套件更多次,您可以将
rebuild
选项添加到./mach try
中。例如,以下命令允许在 try 上运行 20 次 necko xpcshell-tests。
./mach try fuzzy netwerk/test/unit --rebuild 20
如果我们确实需要调试间歇性测试失败,请首先参阅此 文档 获取一些一般提示。不幸的是,没有简单的方法可以调试它。可以先尝试隔离失败的测试,并在 try 上启用
HTTP logging
以收集日志以供进一步分析。
编写 Necko XPCShell 测试¶
最典型的 necko xpcsehll-test 形式是创建 HTTP 服务器,并通过让服务器返回一些特定响应(例如,103 Early Hint
)来测试您的代码。本文档仅介绍如何编写此类测试。
服务器端代码
在 bug 1756557 之后,可以在测试代码中创建
nodejs
HTTP 服务器。通过重用nodejs
提供的 HTTP 模块,这节省了我们编写服务器端代码的时间。创建简单 HTTP 服务器的代码如下所示let server = new NodeHTTPServer(); await server.start(); registerCleanupFunction(async () => { await server.stop(); }); await server.registerPathHandler("/test", (req, resp) => { resp.writeHead(200); resp.end("done"); });
我们还可以通过将
NodeHTTPServer
替换为NodeHTTP2Server
并添加服务器证书来轻松创建HTTP/2
服务器。let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( Ci.nsIX509CertDB ); addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u"); let server = new NodeHTTP2Server();
客户端代码
推荐的方法是创建并打开 HTTP 通道,并使用
Promise
异步处理响应。代码如下所示function makeChan(uri) { let chan = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true, }).QueryInterface(Ci.nsIHttpChannel); chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI; return chan; } let chan = makeChan(`https://127.0.0.1:${server.port()}/test`); let req = await new Promise(resolve => { chan.asyncOpen(new ChannelListener(resolve, null, CL_ALLOW_UNKNOWN_CL)); });
将所有内容放在一起的代码如下所示
add_task(async function test_http() { let server = new NodeHTTPServer(); await server.start(); registerCleanupFunction(async () => { await server.stop(); }); await server.registerPathHandler("/test", (req, resp) => { resp.writeHead(200); resp.end("done"); }); let chan = makeChan(`https://127.0.0.1:${server.port()}/test`); let req = await new Promise(resolve => { chan.asyncOpen(new ChannelListener(resolve, null, CL_ALLOW_UNKNOWN_CL)); }); equal(req.status, Cr.NS_OK); equal(req.QueryInterface(Ci.nsIHttpChannel).responseStatus, 200); equal(req.QueryInterface(Ci.nsIHttpChannel).protocolVersion, "http/1.1"); });