测试模块

本文将就如何构建使用 Rust 自动化测试框架的 rust_test 模块提供基本信息。

编写基本的 Rust 测试

如需查看设备上和主机上的 Rust 测试实际示例,请查看 keystore2 Android.bp,或者从 external/rust/crates 目录中的许多 crate 中找一个查看。

rust_test 模块使用 rustc 的 --test 标志构建,该标志以标记有 #[test] 属性的代码创建测试。如需了解详情,请参阅 Rust 参考测试属性文档。

按以下方式定义测试模块:

rust_test {
    name: "libfoo_inline_tests",

    // Specify the entry point of your library or binary to run all tests
    // specified in-line with the test attribute.
    srcs: ["src/lib.rs"],

    // Tradefed test suite to include this test in.
    test_suites: ["general-tests"],

    // Autogenerate the test config
    auto_gen_config: true,

    rustlibs: [
        "libfoo",
    ],
}

TEST_MAPPING 文件包含测试列表。虽非强制性要求,但如果您确实创建了 TEST_MAPPING 文件,其中包含的测试将在提交前测试中运行,并可以使用 atest 进行调用。

您可以参考 TEST_MAPPING 文档了解其详情,但对于 libfoo_inline_tests 示例,请将以下代码添加到提交前测试中,使您的测试能够在 TreeHugger 上运行:

{
  "presubmit": [
    {
      "name": "libfoo_inline_tests",
    },
  ]
}

请注意,除非将 unit_tests: 设为 false,否则默认情况下 rust_test_host 模块会在提交前测试中运行,因此您无需在 TEST_MAPPING 文件中声明这些模块。

如需详细了解 auto_gen_configtest_suites 属性的工作方式,请参阅测试开发工作流文档的设置部分。

重要的 Rust 测试属性

rust_test 模块从 rust_binary 模块继承属性,如二进制模块页面中所述。

除了适用于所有模块的重要的通用属性之外,还有下表中定义的一些属性。这些属性要么对 Rust 测试模块特别重要,要么具有特定于 rust_test 模块类型的独有行为。

  • test_harness:高级用法,默认设为 true。

如果您的 rust_test 实现了自己的自动化测试框架,您不需要使用内置的 Rust 自动化测试框架,请将此属性设为 false(换言之,将此属性设为 false 就不会将 --test 标志传递给 rustc)。

避免 rust_library 和 rust_test 之间出现重复

通过嵌套模块使用内嵌 Rust 测试时,最终会导致 Android.bp 文件中出现重复。问题在于,您必须为 rust_libraryrust_test 各列出一次依赖项:

rust_library {
    name: "libfoo",
    srcs: ["src/lib.rs"],
    rustlibs: [
        "libx",
        "liby",
        "libz",
    ],
}

rust_test {
    name: "libfoo_inline_tests",
    srcs: ["src/lib.rs"],
    test_suites: ["general_tests"],
    rustlibs: [
        "libx",
        "liby",
        "libz",
    ],
}

每个 rust_test 模块最终都会列出与对应的 rust_library 模块相同的依赖项。为确保不同模块之间的一致性,您可以在 rust_defaults 模块中仅列出一次依赖项:

rust_defaults {
    name: "libfoo_defaults",
    srcs: ["src/lib.rs"],
    rustlibs: [
        "libx",
        "liby",
        "libz",
    ],
}

rust_library {
    name: "libfoo",
    defaults: ["libfoo_defaults"],
}

rust_test {
    name: "libfoo_inline_tests",
    defaults: ["libfoo_defaults"],
    test_suites: ["general_tests"],
}

这样,库和测试模块将始终使用相同的依赖项。