本页提供了使用 fx test 命令在
Fuchsia 源代码检出设置
(fuchsia.git) 中运行测试的最佳实践、示例和参考资料
。
基本用法
如需开始使用,只需运行 fx test:
fx test此命令将执行以下几项操作:
- 识别当前 build 中包含的测试。
- 根据选择条件选择一部分包含的测试。
- 重新构建并重新发布这些测试。
- 检查是否存在合适的 Fuchsia 设备来运行测试。
- 并行开始在该设备上运行测试,并提供状态输出。
- 编写一个日志文件,描述发生的操作。
如果您未在 build 中包含任何测试,fx test 将退出。
在
fx set命令行中尝试fx set core.x64--with //src/diagnostics:tests,以包含一些测试作为示例。
如需详细了解 fx test 的当前状态,请参阅此
README 页面。
基本概念
fx test 是一个 测试执行器,这意味着它会接收
可用测试的列表,并负责安排和观察
这些测试的执行情况。此数据的来源是
tests.json。
tests.json 中列出的每个测试都是一个测试套件 ,每个测试套件可能包含任意数量的测试用例 。也就是说,测试套件是一个
二进制文件或 Fuchsia 组件,它包含以特定于每个测试框架的方式定义的测试用例
(例如
C++ TEST、Rust #[test]、Python unittest.TestCase)。枚举
和执行设备上的测试用例是
测试运行器
框架的责任。
基本测试选择
fx test 支持使用命令行选项选择单个测试套件。 这样,您就可以在 build 中包含大量测试,然后仅执行这些测试的一部分。
fx test 的任何非标志参数都是一个选择 ,该选择与输入中的每个测试进行模糊匹配:
fx test archivist --dry默认情况下,系统会搜索以下字段:
| 字段 | 说明 |
|---|---|
| 名称 | 测试的完整名称。对于设备上测试,这是组件网址;对于主机测试,这是测试二进制文件路径。 |
| 标签 | 测试的 build 标签。例如,//src/examples:my_test。 |
| 组件名称 | 仅适用于设备上测试的组件清单的名称(不包括 .cm)。 |
| 软件包名称 | 仅适用于设备上测试的 Fuchsia 软件包的名称。 |
您可以通过列出前缀来选择源代码树中某个目录下的所有测试:
fx test //src/diagnostics/tests --dry默认情况下,系统会匹配上述所有字段,但您可以使用 --package 或 --component 选择特定字段:
fx test --package archivist_unittests --dry默认情况下,命令行上的多个选择会实现包含性 OR 运算。测试选择支持复合 AND 运算,如下所示:
fx test --package archivist --and unittests --dry此命令会选择软件包与 archivist 匹配且任何字段与 unittests 匹配的所有测试。
如果您知道要执行的测试的确切名称,可以使用 --exact 标志仅选择该测试:
fx test --exact fuchsia-pkg://fuchsia.com/archivist-tests#meta/archivist-unittests.cm --dry如果没有测试与您的选择匹配,fx test 将尝试以启发式方式匹配源代码检出中的测试,并建议 fx set 参数以包含这些测试:
$ fx test driver-tests --dry
...
For `driver-tests`, did you mean any of the following?
driver_tools_tests (91.67% similar)
--with //src/devices/bin/driver_tools:driver_tools_tests
driver-runner-tests (90.96% similar)
--with //src/devices/bin/driver_manager:driver-runner-tests
driver-inspect-test (90.96% similar)
--with //src/devices/tests/driver-inspect-test:driver-inspect-test
然后,您可以将必要的软件包添加到 build 中。
基本测试输出
fx test 将其输出存储在日志文件中,以供日后分析。您可以使用 -pr/--previous 参数以文本形式查看此日志文件的摘要。例如,如需查看上次运行的测试日志:
$ fx test -pr log
previous-log-file.json.gz:
4 tests were run
[START first_test]
...
[END first_test]
如需查看用于处理先前日志文件的完整选项列表,请运行 fx test -pr help。
默认情况下,此命令会处理存储在 Fuchsia 输出目录中的最新日志,但您可以传递 --logpath 以选择特定日志。
此命令对损坏或不完整的日志文件具有弹性,因此即使您终止运行测试的 fx test 命令,它也应该仍然有效。
基本测试调试
fx test 与 zxdb 集成,提供了一种简单易用的方式来调试测试失败,而无需重新编译任何内容。将 --break-on-failure 传递给 fx test 调用,以自动让测试失败中断到调试器中:
$ fx test --break-on-failure rust_crasher_test.cm
...
⚠️ zxdb caught test failure in rust_crasher_test.cm, type `frame` to get started.
14 LLVM_LIBC_FUNCTION(void, abort, ()) {
15 for (;;) {
▶ 16 CRASH_WITH_UNIQUE_BACKTRACE();
17 _zx_process_exit(ZX_TASK_RETCODE_EXCEPTION_KILL);
18 }
══════════════════════════
Invalid opcode exception
══════════════════════════
Process 1 (koid=107752) thread 1 (koid=107754)
Faulting instruction: 0x4159210ab797
🛑 process 1 __llvm_libc::__abort_impl__() • abort.cc:16
[zxdb] // Now you can debug why the test failed!
您还可以使用 --breakpoint=<location> 选项在代码中的任何特定
位置设置断点。<location> 采用标准 zxdb 断点
语法,通常是文件和行号或函数名称:
--breakpoint=my_file.rs:123在 my_file.rs 的第 123 行设置断点。--breakpoint=some_function在some_function上设置断点。
请注意,此选项会导致测试运行速度显著降低,因为 zxdb 需要加载测试的所有符号才能安装断点。强烈建议您仅将此选项与 --test-filter 结合使用。
调试完测试失败后,您可以输入 quit、ctrl+d 或 detach * 以恢复运行测试。请注意,如果存在多个测试用例失败,系统不会暂停以让您调试这些测试。如需详细了解如何调试并行发生的多个
测试失败,请参阅
调试测试。
配置选项
fx test 是高度可配置的,如需查看完整的选项列表,请访问 fx test --help。
本部分介绍了如何指定配置选项及其含义。配置选项分为实用程序选项、build 选项、测试选择选项、执行选项或输出选项。它们可以在命令行中指定,也可以在配置文件中指定。
配置文件
fx test 的所有参数都在命令行中设置,但可以为每个用户设置默认值。如果您在主目录中放置一个名为 .fxtestrc 的文件,则该文件中的参数将成为未来 fx test 调用的新默认值。
例如:
# ~/.fxtestrc
# Lines starting with "#" are comments and ignored.
# The below config roughly matches the behavior of the old Dart-based `fx test`.
# Default parallel to 1.
--parallel 1
# Disable status output.
--no-status
# Print output for tests taking longer than 2 seconds.
--slow 2
上述文件会替换 --parallel 和 --status 标志的默认值,这两个标志通常分别默认为 4 和 false。在调用 fx test 时,仍然可以在命令行中替换新默认值。
实用程序选项
实用程序选项会更改 fx test 的整体行为。
--dry 执行“试运行”。fx test 将完成测试选择,但随后只会输出所选测试套件的列表,而不会执行任何测试套件。
--list 在“列表模式”下运行 fx test。此命令不会执行测试,而是列出每个测试套件中的所有测试用例。 它会输出相应的命令行来运行每个单独的用例。请注意,这确实需要访问 Fuchsia 设备或模拟器,因为用例由设备上的测试管理器枚举。
-pr/--prev/--previous COMMAND 将处理上次执行 fx test 的日志文件,并根据 COMMAND 的值输出信息。不会执行任何新测试。
此命令遵循 --logpath 来指定要从中读取的日志。
实现了以下 COMMAND:
log输出日志文件中记录的每个测试的命令行和输出。path输出最新日志文件的路径。replay将使用新的显示选项重播上次运行。 可以使用--replay-speed参数控制重播速度。值 > 1 会加快输出速度,值 < 1 会以慢动作显示运行。stats将输出有关上次运行的统计信息,包括最长的操作以及按类别划分的执行时间摘要。help输出可用命令的摘要。
build 选项
fx test 默认构建和更新所选测试。这在运行 fx -i test 时非常有用,该命令会检测对源目录的更改,并在每次修改文件后重新调用 fx test。测试重新构建的工作方式如下(内联列出了替换项)。
- 系统会通过为每个
fx test调用调用fx build <targets>来重新构建所有选定的测试。- 使用
--[no-]build切换此行为。
- 使用
- 如果所选测试位于 build 的指定软件包中
(使用
fx set --with-test指定),则系统会构建updates软件包 并执行 OTA。- 使用
--[no-]updateifinbase切换此行为。 - 警告:以模拟器为目标时,OTA 将失败。
- 使用
测试选择选项
以下选项会影响 fx test 选择哪些测试以及如何应用选择。
--host 和 --device 分别仅选择主机测试或设备测试。这是一个全局设置,不能组合使用。
--[no-]e2e 控制是否运行端到端 (E2E) 测试。
默认情况下,系统不会运行 E2E 测试,因为它们可能会使设备处于无效状态。--only-e2e 意味着 --e2e,并确保仅选择 E2E 测试。
--package (-p) 和 --component (-c) 分别在软件包名称或
组件名称中进行选择。前面既没有也没有的名称不会选择任何测试字段。
可以使用 --and (-a) 更改多个选择。例如:
fx test --package foo -a --component bar //src/other --and --package my-tests上面的命令行包含两个选择子句:
- 软件包“foo”AND 组件“bar”(例如 fuchsia-pkg://fuchsia.com/foo#meta/bar.cm)。
- 软件包“my-tests”AND //src/other。
系统会选择与上述任一子句匹配的测试。
默认情况下,测试选择使用 Damerau-Levenshtein 距离 3 进行模糊匹配(例如,“my_tset”将与“my-test”匹配)。
--fuzzy <N> 可用于将此值替换为 N,其中
0 表示不进行模糊匹配。
如果没有任何测试与选择子句匹配,系统会默认显示建议。可以使用
--suggestions-count N替换建议数量(默认值为 6),并且可以使用
--[no-]show-suggestions停用或启用建议。
执行选项
测试以特定方式执行,以最大限度地提高吞吐量和稳定性,但可以替换此默认值的每个元素。测试的执行方式如下(内联列出了替换项):
- 每个选定的测试都按照它们在
tests.json-
中出现的顺序执行
- 使用
--random随机化此执行顺序。
- 使用
- 系统会运行所有选定的测试,从上面有序列表的开头开始。
- 使用
--offset N跳过列表开头的N个测试。默认值为 0。 - 使用
--limit N从偏移量运行最多N个测试。默认值为无限制。
- 使用
- 最多可以并行运行 4 个测试,其中最多一个测试是“非密封的”(由
test-list.json确定)。- 使用
--parallel N更改此默认值。--parallel 1表示按顺序执行每个测试。
- 使用
- 测试会一直运行,直到自行终止。
- 使用
--timeout N为每个测试等待最多N秒。
- 使用
- 每个测试运行一次。
- 使用
--count N运行每个测试N次。
- 使用
- 如果测试的任何执行失败,系统将跳过其余的重复执行。
- 使用
--no-fail-by-group继续运行,直到达到--count指定的上限。
- 使用
- 系统会从每个测试运行所有测试用例。
- 使用
--test-filter仅运行特定命名的测试用例。
- 使用
- 系统会记录失败的测试,并继续执行下一个选定的测试。
- 使用
--fail(-f) 在第一次失败后终止所有测试。
- 使用
- 如果在
tests.json中指定最大日志级别的测试看到严重程度较高的日志,则会失败。- 使用
--[no-]restrict-logs切换此行为。
- 使用
- 测试组件本身会选择要输出的最低日志严重程度。
- 使用
--min-severity-logs替换所有测试组件的此最小值。
- 使用
- 测试组件使用 build 制品的 Merkle 根哈希运行,这可确保成功将构建的最新版本推送到目标并正在运行。
- 使用
--[no-]use-package-hash切换此行为。
- 使用
- 系统不会运行已停用的测试用例。
- 使用
--also-run-disabled-tests无论如何都要运行已停用的测试用例。
- 使用
- 测试输出日志仅包含组件 Moniker 的最后一个片段,因此更易于直观检查。
- 使用
--[no-]show-full-moniker-in-logs切换此行为。
- 使用
失败的测试会在失败后终止,而无需等待
- 使用
--break-on-failure通过 zxdb 捕获失败的测试。 - 使用
--breakpoint=<location>在特定 [位置][#basic-test-debugging]安装断点。
请注意,使用
--breakpoint选项会显著减慢测试速度。强烈建议您仅将此选项与--test-filter结合使用。--break-on-failure可用于许多测试,对性能的影响极小。- 使用
测试的命令行实参完全由测试运行器控制
- 将
--附加到实参,以将剩余实参原封不动地传递给测试。例如:fx test foo -- --argument_for_test会将--argument_for_test传递给测试本身。
- 将
主机测试将自动从用户环境中继承一组有限的环境变量
- 使用
--env(-e) 向测试添加新的KEY=VALUE环境变量 到测试。此标志可以指定多次。
- 使用
如果没有软件包服务器正在运行,系统将在
fx test的执行期间启动临时服务器- 使用
--no-allow-temporary-package-server停用此行为。 - 如果找到现有软件包服务器,系统将不会启动临时服务器。
- 使用
输出选项
fx test 适用于开发者用例,并包含一个简单的终端界面,用于显示测试的执行状态。默认输出行为如下(内联列出了替换项):
- 状态显示在终端底部,并且会自动更新以显示当前正在执行的操作。
- 使用
--[no-]status切换状态显示。 - 使用
--status-lines N更改状态输出行的数量。 - 使用
--status-delay N更改刷新率(默认值为 0.033 或大约 30Hz)。如果您的终端速度较慢,您可能需要将其更改为 0.5 或 1。
- 使用
- 输出采用 ANSI 终端颜色设置样式。
- 使用
--[no-]style切换此行为。 - 使用
--simple作为--no-style --no-status的简写。
- 使用
- 测试输出仅针对失败的测试显示。
- 使用
--output(-o) 显示所有测试输出(与--parallel 1结合使用可防止交错)。 - 使用
--no-output显式隐藏输出,例如替换配置中设置的--output。 - 使用
--slow N(-s N) 仅显示执行时间超过N秒的测试套件 的输出。
- 使用
- 日志会写入
fx status指定的 build 目录下的带时间戳的.json.gz文件。- 使用
--[no-]log完全切换日志记录。 - 使用
--logpath更改日志的输出路径。
- 使用
- 测试制品不会从设备流式传输。
- 使用
--artifact-output-directory(--outdir) 指定一个目录,制品可以在该目录中以ffx test输出格式流式传输。
- 使用
- 调试输出被抑制。
- 使用
--verbose(-v) 将调试信息输出到控制台。 此数据非常详细,仅对调试fx test本身有用。
- 使用
日志格式
fx test 旨在通过将每个用户可见的输出表示为“事件”来支持外部工具,这些事件在执行期间记录到文件中。
日志文件使用 gzip 压缩。解压缩文件的每一行都是一个 JSON 对象,表示一个事件。事件 架构目前在此 Python 文件中定义。
当格式稳定后,就可以构建交互式 查看器和转换器,以转换为其他格式(例如 Build Event Protocol)。
常见问题
fx test 无法与 emacs 搭配使用
emacs 编译窗口不会模拟与 xterm 兼容的终端,从而导致如下错误:
in _make_progress_bar raise ValueError("Width must be at least 3")
如需解决此问题,请使用 --no-status 选项运行 fx test 以停用状态栏。
转义序列显示在 fx test 输出中
您的终端可能不支持 ANSI 颜色代码,fx test 无法检测到这些代码。
将 --no-style 选项传递给 fx test 以停用颜色输出,或将 --no-status 选项传递给 fx test 以停用更新状态栏。将 --simple 选项传递给 fx test 等同于 --no-style --no-status。
我不知道我的日志文件在哪里
您可以将 --logpath 传递给 fx test 来设置日志的位置,但建议仅在非互动式使用时这样做。
默认情况下,日志会以带时间戳的文件形式存储在 Fuchsia 输出目录中。使用 fx test -pr path 输出先前日志的路径。
输出日志文件会将垃圾内容转储到我的终端中
fx test 日志默认采用 gzip 压缩。使用以下命令将最新日志以美观格式输出到终端:
cat `fx test -pr path` | gunzip | jq -C | less -R
此命令执行以下操作:
- 查找最新日志路径 (
fx test -pr path)。 - 将日志通过管道传输到
gunzip以解压缩日志。 - 将解压缩的日志通过管道传输到
jq以使用颜色输出 (-C) 以美观格式输出日志。 - 将颜色输出通过管道传输到配置为显示颜色 (
-R) 的less。
为方便起见,您可以在 .bashrc 文件中为此命令添加别名:
alias testlog='cat `fx test -pr path` | gunzip | jq -C | less -R'