测试:问题和答案

欢迎在此处添加您自己的问题(和答案)!

问题:如何定义新的单元测试?

答:使用适合语言的构造,例如适用于 C++ 的 GTest。您可以根据需要定义新文件,例如:

(在 BUILD.gn 文件中)

executable("unittests") {
  output_name = "scenic_unittests"
  testonly = true
  sources = ["some_test.cc"],
  deps = [":some_dep"],
}

问:如何确保它会运行?

答:测试以 GN 基于 fx set 参数生成的 FUCHSIA_BUILD_DIR/tests.json 文件中的条目表示。用于创建或更新 tests.json 的步骤称为 build 的 gen 阶段,它由 fx setfx build 或显式由 fx gen 触发。

如果 fx test 找不到您的测试,请先检查 FUCHSIA_BUILD_DIR/tests.json。在大多数情况下,产品配置以及 fx set 命令的 --with 参数直接或间接缺少您尝试运行的测试。如果是这种情况,只需将测试 GN 标签或将测试作为 --with 参数传递的 GN 标签添加到 fx set 命令中,例如:

fx set ... --with //src/sys:tests

某些商品或款式/规格配置也可能会停用测试。如果 fx test 在使用 fx set 添加标签后找不到测试,请验证该测试是否未被 build 规则排除。例如,测试可能会被排除在覆盖率变体中。这在测试的 BUILD.gn 文件中可能如下所示:

group("tests") {
  if (!is_coverage) {
    deps = [ ":my-test" ]
  }
}

如果新添加的测试位于由 fx set 定义的产品配置中,但仍未显示在 tests.json 中,您可能需要运行 fx genfx build 来更新 tests.json,以便 fx test 知道如何运行它。

问:如何在 QEMU 实例上运行此单元测试?

如果 QEMU 支持网络连接,则可以采用简单的方法;如果不支持,则可以采用复杂的方法。

方法 A(有网络连接):在一个终端中,使用 fx qemu -N 启动 QEMU 实例。 接下来,在另一个终端中,输入 fx test escher_tests

此调用会运行 escher_tests 软件包中的所有测试可执行文件。

A(无网络):启动 QEMU 实例 (fx qemu),然后手动调用 run-test-suite 命令。

在 QEMU shell 中,输入 run-test-suite <test_url>

请注意!在没有网络的情况下,这些文件会在启动时加载到 QEMU 实例中。因此,重新构建测试后,您需要关闭并重新启动 QEMU 实例,才能查看重新构建的测试。

如需退出 QEMU,请按 power shutdown

问:如何在开发设备上运行此单元测试?

答:手动调用(如在 QEMU 中)对正在运行的设备执行 fx test

请注意,启动时,已启动的设备可能不包含您的二进制文件,但 fx test 会构建测试二进制文件,将其发送到设备并运行它,同时将输出管道化回您的工作站终端。光滑!

确保您的设备正在运行(按 Ctrl-D 启动现有映像)并已连接到您的工作站。

在工作站上,fx test escher_tests 将串行运行 escher_tests 软件包中包含的所有测试可执行文件。

如需仅运行一个测试可执行文件,请使用以下命令:

fx test <executable-name>

您可以使用 fx -i 在每次源文件更改时自动重新构建、安装和运行测试。例如:fx -i test escher_tests

问:测试结果在哪里捕获?

答:输出会发送到您的终端。

确实有一种方法可以将测试输出写入文件(包括摘要 JSON 文件),CQ 聊天机器人就是通过这种方式收集自动运行的测试输出。

问:如何停用测试?如何查找和运行已停用的测试?

答:您可以通过多种方式执行此操作。每当执行上述任何操作时,请务必提交 bug,并在停用测试的代码中通过注释引用该 bug。

将测试标记为不可靠

为此,您可以在测试环境中的 tags 字段中添加“flaky”。这会对整个测试目标(对应于可执行文件)进行操作。这将阻止此目标在提交队列中的构建器上运行,并在继续在 CI 中运行测试的特殊不稳定构建器上启用该目标。请务必在 BUILD.gn 文件的注释中记录该 bug。更改示例

如果您只想停用大型测试目标中的部分测试,则需要将该目标拆分为两个 GN 目标,并将其中一个标记为不稳定。

仅限 C++ googletest:为名称添加 DISABLED 前缀

如需在较大的测试可执行文件中停用特定测试,您可以将其标记为已停用。已停用的测试的名称前面会带有 DISABLED_ 前缀。因此,查找它们的一种方法就是使用 git grep DISABLED_

如需强制运行已停用的测试,请使用 fx test escher_tests --also-run-disabled-tests

仅限 Rust:应用 #[ignore] 属性

如需在较大的 Rust 测试可执行文件中停用特定测试,您可以使用 #[ignore] 标记该测试。应将其应用在 #[test] 属性下方。

示例:

#[test]
#[ignore] // TODO(https://fxbug.dev/NNNNN) re-enable this test when de-flaked
fn flaky_test_we_need_to_fix() { ... }

标记测试已停用

或者,您也可以在包含多个测试可执行文件的软件包中停用整个测试可执行文件。为此,请按如下所示修改 BUILD.gntests = [ { name = "scenic_unittests", disabled = true } ]。因此,scenic_unittests 将被放入 /pkgfs/packages/<package_name>/0/testdisabled 子目录中,并且不会由 CQ 系统运行。

注释掉测试

如需在较大的测试可执行文件中停用特定测试,您可以注释掉定义该测试的代码。

问题:如何自动运行一组测试?如何确保所有依赖项都已测试?

答:fx test 的主要功能是批量执行。如需查看有关如何一起运行多个测试或测试套件的示例,请参阅运行 Fuchsia 测试

此外,您可以随时将补丁上传到 Gerrit 并进行 CQ 模拟运行。

问题:如何在 CQ 模拟运行中运行此单元测试?

答:点击 CQ 预演(也称为“+1”)后,系统会获取您更改的正确定义的单元测试,并在多个机器人上运行该测试(每个 build 目标对应一个测试,例如 x86-64arm64releasedebug)。每个作业都有一个输出页面,其中会显示运行的所有测试。

问:如何在单元测试中使用一些构建时工件?

答:最简单的工件只是源目录中的文件。为此,您只需将其添加到单元测试软件包定义的 resources 属性即可。例如,您可以在 BUILD.gn 中执行如下操作:

rustc_binary("my-great-app") {
  with_unit_tests = true

  ...
}

test_package("my-great-app-tests") {
  deps = [
    ":my-great-app_test",
  ]

  resources = [
    {
      path = "source.zip"
      dest = "testing.zip"
    }
  ]

该文件将作为 /pkg/data/testing.zip 在将执行测试二进制文件的环境中提供。

TODO:如果您希望在 build 流程中生成工件,则可能需要将用于生成工件的规则添加到 test_package 规则的 data_deps 数组中。但我还没有试过。请在尝试后更新此部分 :)