借助 Fuchsia 测试运行程序框架,开发者能够使用各种语言和运行时为组件构建测试,并在目标设备上执行这些测试。该框架提供了测试运行程序组件,可实现 fuchsia.test.Suite
协议并与通用语言专用测试框架(例如 GoogleTest (C++))集成。
test_manager
组件负责在 Fuchsia 设备上运行测试。它会检查实现测试套件协议的组件,并将其作为子组件启动。这意味着,test_manager
还负责为每个测试套件提供功能,从而创建通常所谓的“测试领域”。
开发者工具(如 ffx test
)会与设备上的 test_manager
通信,以执行测试套件并检索结果。
测试运行程序
测试运行程序是测试运行程序框架与开发者用于以其首选语言编写测试的通用框架之间的可重复使用适配器。每个测试运行程序组件都会公开 fuchsia.test.Suite
功能,以便 test_manager
枚举和执行各个测试,并声明支持测试框架的适当执行 runner
。
{
// Execute tests using language-specific runner
program: { runner: "elf_test_runner", },
// Expose test suite protocol to test manager
capabilities: [
{ protocol: "fuchsia.test.Suite" },
],
expose: [
{
protocol: "fuchsia.test.Suite",
from: "self",
},
],
}
为了简化集成,测试运行程序框架为每个特定于语言的运行程序提供了清单分片。下面是一个等效的测试运行程序 CML,用于声明前面示例组件测试中的功能。
{
include: [ "sys/testing/elf_test_runner.shard.cml" ]
}
单元测试
单元测试侧重于验证组件中的各个代码单元,并与系统上的其他组件隔离开来。单元测试应该是封闭测试,也就是说,它们不需要测试,也不需要提供测试之外的其他功能。
Fuchsia SDK 提供了其他模板来帮助创建单元测试组件:
fuchsia_cc_test()
:将 C++ 源代码编译到测试二进制文件中。添加到软件包时,此规则还会生成一个引用测试二进制文件且不需要其他功能的最小组件清单。fuchsia_test_package()
:生成包含一个或多个测试组件及其依赖项的 Fuchsia 软件包。
以下是用于添加单元测试的 BUILD.bazel
代码段示例:
load(
"fuchsia_cc_test",
"fuchsia_select",
"fuchsia_test_package",
)
fuchsia_cc_test(
name = "hello_world_test",
srcs = ["hello_world_test.cc"],
deps = fuchsia_select({
"@platforms//os:fuchsia": [
"@fuchsia_sdk//pkg/fdio",
"@fuchsia_sdk//pkg/syslog",
],
}),
)
fuchsia_test_package(
name = "unit_test_pkg",
visibility = ["//visibility:public"],
deps = [
":hello_world_test",
],
)
练习:Echo 单元测试
在本练习中,您将使用测试运行程序框架向 echo
组件添加单元测试,并在 FEMU 环境中运行这些测试。
完成本部分后,项目应具有以下目录结构:
//fuchsia-codelab/echo
|- BUILD.bazel
|- meta
| |- echo.cml
|
|- echo_component.cc
|- echo_component.h
|- echo_unittest.cc
|- main.cc
echo_unittest.cc
:C++ 单元测试的源代码。
实现单元测试
单元测试可验证组件的内部函数是否按预期运行。对于 echo
组件,您将验证上一个练习中使用的 greeting()
函数是否返回预期值。
创建 echo/echo_unittest.cc
并添加以下单元测试函数,以便在获得 1 个、2 个或 3 个参数时验证 greeting()
函数的行为:
echo/echo_unittest.cc
:
#include <gtest/gtest.h>
#include "echo_component.h"
TEST(EchoTest, TestGreetOne) {
std::vector<std::string> names = {"Alice"};
std::string expected = "Alice";
ASSERT_TRUE(echo::greeting(names) == expected);
}
TEST(EchoTest, TestGreetTwo) {
std::vector<std::string> names = {"Alice", "Bob"};
std::string expected = "Alice and Bob";
ASSERT_TRUE(echo::greeting(names) == expected);
}
TEST(EchoTest, TestGreetThree) {
std::vector<std::string> names = {"Alice", "Bob", "Spot"};
std::string expected = "Alice, Bob, Spot";
ASSERT_TRUE(echo::greeting(names) == expected);
}
运行单元测试
更新 echo/BUILD.bazel
文件的导入部分,以包含其他测试规则:
echo/BUILD.bazel
:
load(
"@rules_fuchsia//fuchsia:defs.bzl",
"fuchsia_cc_binary",
"fuchsia_cc_test",
"fuchsia_component",
"fuchsia_component_manifest",
"fuchsia_package",
"fuchsia_test_package",
"if_fuchsia",
)
添加以下构建规则,以将您的测试包含在 build 配置中:
echo/BUILD.bazel
:
fuchsia_cc_test(
name = "echo_unittests",
size = "small",
srcs = [
"echo_component.cc",
"echo_component.h",
"echo_unittest.cc",
],
visibility = ["//visibility:public"],
deps = ["@com_google_googletest//:gtest_main"] + if_fuchsia([
"@fuchsia_sdk//pkg/fdio",
"@fuchsia_sdk//pkg/sys_cpp",
"@fuchsia_sdk//pkg/syslog",
]),
)
fuchsia_test_package(
name = "test_pkg",
package_name = "echo_unittests",
visibility = ["//visibility:public"],
components = [
":echo_unittests",
],
)
此规则将您的单元测试打包到以下网址的组件中:
fuchsia-pkg://fuchsiasamples.com/echo_unittests#meta/echo_unittests.cm
构建测试软件包并将其发布到 fuchsiasamples.com
代码库:
bazel run //fuchsia-codelab/echo:test_pkg.publish -- \
--repo_name fuchsiasamples.com
使用 ffx test
命令执行此软件包中的单元测试。
验证测试是否通过:
ffx test run \
fuchsia-pkg://fuchsiasamples.com/echo_unittests#meta/echo_unittests.cm