FX 测试用户指南

本页提供了最佳实践、示例和参考资料 使用 fx test 命令运行测试 Fuchsia 源结账设置fuchsia.git)。

基本用法

首先,运行 fx test

fx test

这样做有以下几个好处:

  1. 识别当前 build 中包含的测试。
  2. 根据选择条件,选择包含的测试的子集。
  3. 重新构建并重新发布这些测试。
  4. 检查是否存在合适的 Fuchsia 设备来运行测试。
  5. 同时,开始在该设备上运行测试并提供状态输出。
  6. 写入日志文件,描述发生的操作。

如果您的 build 中未包含任何测试,fx test 将退出。 试用 fx set core.x64--with //src/diagnostics:tests fx set 命令行以包含一些测试作为示例。

如需详细了解fx test的当前状态,请查看此 README 页面。

基本概念

fx test 是一个测试执行器,这意味着它会提取 可用的测试,并负责安排和观察 其执行情况。这些数据的来源是 tests.json

tests.json 中列出的每项测试都是一个测试套件,每个 包含任意数量的测试用例。也就是说,测试套件 单个二进制文件或 Fuchsia 组件,并且其中包含测试用例 每个测试框架都有特定的定义方式(例如 C++ TEST、Rust #[test]、Python unittest.TestCase)。枚举 和执行设备端测试用例的责任是 测试运行程序 框架

基本测试选择

fx test 支持使用命令选择各个测试套件 行选项。这样,您就可以将大量测试 然后只执行其中一部分测试。

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 testzxdb 集成,让您可以简单轻松地调试自己的 测试失败,无需重新编译任何内容。通过 --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

调试完测试失败问题后,您可以输入 quitctrl+d、 或 detach * 以继续运行测试。请注意,如果有多个测试 即使出现失败情况,该测试也不会暂停,以便您也可以调试这些测试。请参阅 调试测试:详细了解如何调试多个 同时发生的测试失败

配置选项

fx test 是高度可配置的, fx test --help提供。

本部分介绍了如何指定配置选项, 具体含义配置选项分为实用程序、 构建、测试选择、执行或输出选项。它们可能是 指定的名称。

配置文件

fx test 的所有参数都在命令行中设置,但可以设置默认值 。如果您将名为 .fxtestrc 的文件放在 HOME 目录中,则该文件中的参数将是将来 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 的默认值 标志,通常分别默认为 4false。新的默认设置 在调用 fx test 时在命令行中仍可能被替换。

实用程序选项

实用程序选项会改变 fx test 的整体行为。

--dry 会执行“试运行”。fx test将完成测试选择,但 然后,系统会直接输出选定测试套件的列表,而不是执行 任意一个。

--list 在“列表模式”下运行 fx test。无需执行 测试,此命令会列出每个测试套件中的所有测试用例。 它会输出相应的命令行以运行每个案例。 请注意,此操作需要访问 Fuchsia 设备或模拟器 因为测试管理器在设备上枚举用例。

-pr/--prev/--previous COMMAND 将从以下位置处理日志文件: 之前执行的 fx test, 具体取决于 COMMAND 的值。不会执行任何新测试。 此命令遵循 --logpath 指定要读取的日志。

实现了以下 COMMAND

  • log 会针对所记录的每个测试输出命令行和输出 记录。
  • help 会输出可用命令的摘要。

构建选项

默认情况下,fx test 会构建和更新所选测试。这是 在运行 fx -i test 时很有用,它会检测 源目录,并在提交每个文件后重新调用 fx test 修改。测试重新构建的运作方式如下(以内嵌方式列出替换项)。

  • 通过调用 fx build <targets> 重新构建所有选定的测试 每次调用 fx test 时。
    • 使用 --[no-]build 可切换此行为。
  • 如果所选测试位于“基础软件包”中适用于您的 build updates 软件包(使用 fx set --with-base 指定) 并执行 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

上述命令行包含两个选择子句:

  1. 软件包“foo”AND 组件“bar”(例如 fuchsia-pkg://fuchsia.com/foo#meta/bar.cm)。
  2. 软件包“my-tests”和 //src/other。

选择与上述任一子句匹配的测试。

测试选择使用 Damerau-Levenshtein 进行模糊匹配 距离为 3(例如“my_tset”将匹配“my-test”)。 --fuzzy <N> 可用于将此值替换为 N,其中 0 表示不进行模糊匹配。

如果没有与所选内容匹配的测试,系统会默认显示建议 子句。您可以使用 --suggestions-count N,如需停用或启用建议功能,请使用 --[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 次。
  • 在每个测试中运行所有测试用例
    • 使用 --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> 在特定位置安装断点 [locations][#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 hz)。如果终端网速很慢 想要将其更改为 0.5 或 1。
  • 输出使用 ANSI 终端颜色设置样式。
    • 使用 --[no-]style 可切换此行为。
    • 使用 --simple 作为 --no-style --no-status 的简写形式。
  • 测试输出仅针对失败的测试显示
    • 使用 --output (-o) 显示所有测试输出(与 --parallel 1 以防止交错)。
    • 使用 --no-output 可显式隐藏输出,例如 替换配置中设置的 --output
    • 使用 --slow N (-s N) 仅显示测试套件的输出 超过 N 秒的执行时间。
  • 日志会写入相应 build 下带有时间戳的 .json.gz 文件 fx status 指定的目录中。
    • 使用 --[no-]log 完全切换日志记录功能。
    • 使用 --logpath 更改日志的输出路径。
  • 测试工件不会流式传输到设备以外。
    • 使用 --artifact-output-directory (--outdir) 指定一个目录 工件可能会以 ffx test 输出格式进行流式传输。
  • 调试打印被抑制。
    • 使用 --verbose (-v) 将调试信息输出到控制台。 此数据极其冗长,仅用于调试 fx test 本身。

日志格式

fx test 旨在支持外部工具,它表示 作为“事件”的用户可见输出系统会在执行期间将其记录到文件中

日志文件是使用 gzip 进行压缩的。每一行解压缩 文件是代表一个事件的单个 JSON 对象。活动 架构当前在 Python 中定义 文件。

格式稳定后,就可以构建互动式广告了 其他格式(例如构建事件 Protocol)。

常见问题

fx 测试无法与 emacs 配合使用

emacs 编译窗口无法模拟与 xterm 兼容的终端, 便会出现如下错误:

in _make_progress_bar raise ValueError("Width must be at least 3")

要解决此问题,请运行 fx test 并使用 --no-status 选项停用 。

转义序列出现在 fx 测试输出中

您的终端可能不支持 fx test 无法检测到的 ANSI 颜色代码。

--no-style 选项传递给 fx test 可停用颜色输出或 --no-status 选项,用于停用状态栏更新功能。传递 将 --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'

选择停用新的 fx 测试命令

新的 fx test 命令当前设置为默认命令。

如需停用此设置,请设置以下环境变量:

export FUCHSIA_DISABLED_legacy_fxtest=0