自动化测试:DevTools mochitests¶
运行 DevTools 的整个浏览器 mochitests 套件(坐下来放松)
./mach mochitest --subsuite devtools --tag devtools
运行特定工具的浏览器 mochitests 套件
./mach mochitest devtools/client/<tool>
例如,运行所有调试器浏览器 mochitests
./mach mochitest devtools/client/debugger
运行特定的 DevTools mochitest
./mach mochitest devtools/client/path/to/the/test_you_want_to_run.js
请注意,mochitests 在运行时**必须**获得焦点。测试在浏览器中运行,看起来像有人在手动测试您的代码。如果浏览器失去焦点,测试将在一段时间后停止并失败。(再次,坐下来放松)
如果您希望运行 mochitests 而无需关心焦点,并在运行时能够触摸您的电脑
./mach mochitest --headless devtools/client/<tool>
您也可以只运行单个测试
./mach mochitest --headless devtools/client/path/to/the/test_you_want_to_run.js
跟踪 JavaScript¶
您可以使用 DEBUG_STEP 环境变量记录 mochitest 脚本中执行的所有行。这将帮助您
如果测试卡在某些异步等待代码上,它在等待哪一行,
将测试脚本执行可视化与各种日志和断言日志进行比较。
请注意,它仅适用于导入 devtools/client/shared/test/shared-head.js
模块的 Mochitests,大多数 DevTools 浏览器 mochitests 使用该模块。
这种方式
DEBUG_STEP=true ./mach mochitest browser_devtools_test.js
或者其他方式
./mach mochitest browser_devtools_test.js --setenv DEBUG_STEP=true
这将记录以下行
[STEP] browser_target_command_detach.js @ 19:15 :: const tab = ↦ await addTab(TEST_URL);
这表明测试脚本在第 19 行和第 15 列即将执行。'↦'突出显示了精确的执行列。
您可以传递毫秒数而不是 true,每个测试行将暂停给定的时间。使用此功能时请小心,因为它将在每个测试行上暂停事件循环并允许处理其他事件。这将导致测试以一种不现实的方式运行,否则不会发生这种情况。
DEBUG_STEP=250 ./mach mochitest browser_devtools_test.js
mochitest 脚本的每一行将暂停 1/4 秒。
最后但并非最不重要的是,此功能可通过以下方式在 try 上使用
./mach mochitest try fuzzy devtools/test/folder/ --env DEBUG_STEP=true
一旦您找到有问题的行,或者想了解有关 mochitest 特定行上发生的事情的更多信息,您就可以使用 DEBUG_TRACE_LINE 环境变量。它需要正在运行的 mochitest 文件的行号,它将跟踪从该代码行运行的所有 JavaScript 代码。
DEBUG_TRACE_LINE=42 ./mach mochitest browser_devtools_test.js
这将记录类似以下内容
0:17.14 GECKO(94170) [STEP] chrome://mochitests/content/browser/devtools/client/webconsole/test/browser/head.js
0:17.14 GECKO(94170) [STEP] ───────────────────────────────────────────────────────────────────────────────────
0:17.14 GECKO(94170) [STEP] 73:36 | async function openNewTabAndConsole↦ (url, clearJstermHistory = true, hostId) {
0:17.15 GECKO(94170) [STEP] 74:19 | const toolbox = ↦ await openNewTabAndToolbox(url, "webconsole", hostId);
0:17.15 GECKO(94170) [STEP]
0:17.15 GECKO(94170) [STEP] chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js
0:17.15 GECKO(94170) [STEP] ──────────────────────────────────────────────────────────────────────────────
0:17.15 GECKO(94170) [STEP] 1273:36 | async function openNewTabAndToolbox↦ (url, toolId, hostType) {
0:17.15 GECKO(94170) [STEP] 1274:15 | const tab = ↦ await addTab(url);
0:17.15 GECKO(94170) [STEP] 531:22 | async function addTab↦ (url, options = {}) {
0:17.15 GECKO(94170) [STEP] 532:3 | ↦ info("Adding a new tab with URL: " + url);
您可以看到函数之间的执行流程,以及函数调用的进度。与 DEBUG_STEP 类似,'↦'符号突出显示了精确的执行位置。
如果此帮助程序不够。您还可以从任何特权代码库中的任何位置手动生成跟踪器,使用以下代码段
const { JSTracer } = ChromeUtils.importESModule(
"resource://devtools/server/tracer/tracer.sys.mjs",
{ global: "contextual" }
);
// You have to at least pass an empty object to startTracing,
// otherwise, all the attributes at optional.
JSTracer.startTracing({
// If you want to log a custom string before each trace
prefix: "[my log]",
// Only if you want to restrict to a specific global,
// otherwise it will trace the current global automatically.
global: window,
// If you are about to call code from another global(s),
// this will trace code from all active globals in the current thread.
// (use only if needed)
traceAllGlobals: true,
// Only if you want to step within function execution (this adds lots of additional traces!)
traceSteps: true,
// If you want to restrict traces to one JS file
filterFrameSourceUrl: "foo.js",
// If you want to avoid logging nested trace above a given threshold
maxDepth: 10,
// If you want the tracer to automatically stop after having logged a given amount of traces
maxRecords: 10,
// If you want to log all DOM events fired on the traced global(s)
traceDOMEvents: true,
// If you want to log all DOM Mutations happening in the traced global(s)
traceDOMMutations: ["add", "attributes", "delete"],
});
[...run some JS code...]
JSTracer.stopTracing();