本页面提供了有关使用 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
默认情况下,系统会搜索以下字段:
字段 | 说明 |
---|---|
name | 测试的完整名称。这是设备端测试的组件网址,以及主机测试的测试二进制文件路径。 |
标签 | 测试的 build 标签。例如,//src/examples:my_test 。 |
组件名称 | 仅适用于设备端测试的组件清单名称(不包括 .cm )。 |
软件包名称 | 仅适用于设备端测试的 Fuchsia 软件包的名称。 |
您可以列出前缀,选择源代码树中某个目录下的所有测试:
fx test //src/diagnostics/tests --dry
默认情况下,系统会匹配上述所有字段,但您也可以使用 --package
或 --component
选择特定字段:
fx test --package archivist_unittests --dry
默认情况下,命令行上的多项选择会实现“或”运算。测试选择支持复合 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
的所有参数均在命令行上设置,但可以按用户设置默认值。如果您在 HOME 目录中放置一个名为 .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 设备或模拟器,因为测试用例由设备上的 Test Manager 枚举。
-pr/--prev/--previous COMMAND
将处理上次执行 fx test
时生成的日志文件,并根据 COMMAND
的值输出信息。不会执行任何新测试。
此命令会遵循 --logpath
来指定要从中读取的日志。
实现了以下 COMMAND
:
log
会输出日志文件中记录的每项测试的命令行和输出。path
会输出最新日志文件的路径。replay
将使用新的显示选项重放之前的运行。您可以使用 --replay-speed 参数控制重放速度。值大于 1 会加快输出速度,值小于 1 会以慢动作显示运行。help
会输出可用命令的摘要。
build 选项
fx test
默认会构建和更新所选测试。在运行 fx -i 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) 测试。默认情况下,系统不会运行端到端测试,因为它们可能会导致设备进入无效状态。--only-e2e
暗示 --e2e
,并确保仅选择端到端测试。
--package
(-p
) 和 --component
(-c
) 分别用于在软件包或组件名称中进行选择。以这两者都不匹配的字符开头的名称不会选择任何测试字段。
可以通过 --and
(-a
) 更改多个选择。例如:
fx test --package foo -a --component bar //src/other --and --package my-tests
上述命令行包含两个选择子句:
- 软件包“foo”和组件“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 项测试,其中最多只有 1 项测试是“非密封”测试(由
test-list.json
确定)。- 您可以使用
--parallel N
更改此默认值。--parallel 1
表示以串行方式执行每个测试。
- 您可以使用
- 测试会一直运行,直到自行终止。
- 使用
--timeout N
时,每项测试最多等待N
秒。
- 使用
- 每项测试都会运行一次。
- 使用
--count N
运行每项测试N
次。
- 使用
- 每个测试都会运行所有测试用例。
- 使用
--test-filter
时,只能运行指定名称的测试用例。
- 使用
- 系统会记录失败的测试,并继续执行下一个所选测试。
- 使用
--fail
(-f
) 在第一次失败后终止所有测试。
- 使用
- 如果在
tests.json
中指定了日志级别上限,则如果出现严重级别更高的日志,测试将会失败。- 使用
--[no-]restrict-logs
可切换此行为。
- 使用
- 测试组件本身会选择要发出的最低日志严重级别。
- 使用
--min-severity-logs
可为所有测试组件替换此最小值。
- 使用
- 测试组件使用 build 工件中的 Merkle 根哈希运行,这可确保成功将构建的最新版本推送到目标并正在运行。
- 使用
--[no-]use-package-hash
可切换此行为。
- 使用
- 系统不会运行已停用的测试用例。
- 无论如何,请使用
--also-run-disabled-tests
运行已停用的测试用例。
- 无论如何,请使用
- 测试输出日志仅包含组件标识名的最后一部分,因此更易于直观检查。
- 使用
--[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-]status
切换状态显示。 - 使用
--status-lines N
更改状态输出行数。 - 使用
--status-delay N
更改刷新率(默认值为 0.033 或大约 30 赫兹)。如果您的终端运行缓慢,您可能需要将此值更改为 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 事件协议)转换为 Interactive Viewer 的转换器。
常见问题
fx 测试不适用于 emacs
emacs 编译窗口无法模拟兼容 xterm 的终端,导致出现如下错误:
in _make_progress_bar raise ValueError("Width must be at least 3")
如需解决此问题,请使用 --no-status
选项运行 fx test
以停用状态栏。
转义序列会显示在 fx 测试输出中
您的终端可能不支持 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
) 以美化格式输出日志。 - 将颜色输出管道化到配置为显示颜色的
less
(-R
)。
为方便起见,您可以在 .bashrc
文件中为此命令添加别名:
alias testlog='cat `fx test -pr path` | gunzip | jq -C | less -R'
停用新的 fx test 命令
新 fx test
命令目前设为默认命令。
如需停用此设置,请设置以下环境变量:
export FUCHSIA_DISABLED_legacy_fxtest=0