集成测试

集成测试侧重于验证组件与系统中的其他组件交互时的行为。因此,集成测试通常与主组件分开构建,并且可能会将受测组件和其他依赖项声明为子组件。根据测试的性质,依赖项组件可能会以模拟或桩的形式提供,以促进测试用例保持封闭状态。

测试组成部分

下面是一个简单集成测试组件的示例组件清单:

meta/integration_tests.cml

{
    include: [
        "//pkg/syslog/client.shard.cml",
        "//pkg/sys/testing/elf_test_runner.shard.cml",
    ],
    program: {
        binary: "bin/client_test",
    },
    children: [
        {
            name: "service",
            url: "fuchsia-pkg://fuchsia.com/foo-package-tests#meta/mock_service.cm",
        },
        {
            name: "client",
            url: "fuchsia-pkg://fuchsia.com/foo-package-tests#meta/foo_client.cm",
        },
    ],
    offer: [
        {
            protocol: "fuchsia.example.Foo",
            from: "#service",
            to: [ "#client" ],
        },
    ],
}

此测试组件声明包含以下关键元素:

  1. 特定于语言的必要测试运行程序分片的 include。这样,测试管理器就可以正确执行测试套件。
  2. 将被测组件和依赖组件列为 children
  3. 在测试领域的组件之间路由所需的功能。

Fuchsia SDK 提供了其他模板,便于创建集成测试组件:

  • fuchsia_cc_test():将 C++ 源代码编译到测试二进制文件中。
  • fuchsia_test_component():使用提供的组件清单生成包含测试的 Fuchsia 组件。您可以将多个测试组件合并到同一个 fuchsia_test_package() 中。

以下示例展示了如何将上述集成测试添加到 BUILD.bazel 文件中:

load(
    "fuchsia_cc_test",
    "fuchsia_component",
    "fuchsia_component_manifest",
    "fuchsia_test_component",
    "fuchsia_test_package",
)

# Component under test
fuchsia_component(
    name = "foo_client",
    manifest = ":foo_client_manifest",
    visibility = ["//visibility:public"],
)

# Test dependencies
fuchsia_component(
    name = "mock_service",
    manifest = ":mock_service_manifest",
    visibility = ["//visibility:public"],
)

# Component containing integration tests
fuchsia_cc_test(
    name = "client_integration_test",
    srcs = [ ... ],
    deps = [ ... ],
)
fuchsia_component_manifest(
    name = "integration_test_manifest",
    src = "meta/integration_tests.cml",
)
fuchsia_test_component(
    name = "integration_test_component",
    manifest = ":integration_test_manifest",
    test_name = "client_integration_test",
    visibility = ["//visibility:public"],
    deps = [":client_integration_test"],
)

# Hermetic test package
fuchsia_test_package(
    name = "integration_test_pkg",
    visibility = ["//visibility:public"],
    deps = [
        ":foo_client",
        ":mock_service",
        ":integration_test_component",
    ],
)

此集成测试 build 配置包含以下关键元素:

  1. 描述集成测试组件及其组件清单的 fuchsia_test_component() 目标。
  2. 其他 fuchsia_component() 目标,表示集成测试所需的组件依赖项。
  3. 单个封闭 fuchsia_test_package(),可将测试组件和所有依赖项捆绑在一起。

练习:Echo 服务器集成测试

在本练习中,您将添加一个集成测试组件,以使用测试运行程序框架来练习 echo_server 组件的 FIDL 协议接口,并在 FEMU 环境中运行这些测试。

添加集成测试组件

首先,在 Bazel 工作区中创建一个新的项目目录:

mkdir -p fuchsia-codelab/echo-integration

完成本部分后,项目应具有以下目录结构:

//fuchsia-codelab/echo-integration
                  |- BUILD.bazel
                  |- meta
                  |   |- echo_integration_test.cml
                  |
                  |- echo_integration_test.cc

创建测试组件清单

创建 echo-integration/meta/echo_integration_test.cml 测试组件清单,将 echo-server 组件声明为子组件,并将 Echo 协议功能路由到测试组件。

echo-integration/meta/echo_integration_test.cml

{
    include: [
        "syslog/client.shard.cml",
        "sys/testing/elf_test_runner.shard.cml",
    ],

    // Information about the program to run.
    program: {
        // The binary to run for this component.
        binary: "bin/echo_integration_test",
    },

    // Child components orchestrated by the integration test.
    children: [
        {
            name: "echo_server",
            url: "#meta/echo_server.cm",
        },
    ],

    // Capabilities used by this component.
    use: [
        {
            protocol: [ "examples.routing.echo.Echo" ],
            from: "#echo_server",
        },
    ],

    // Capabilities required by components under test.
    offer: [
        {
            protocol: [ "fuchsia.logger.LogSink" ],
            from: "parent",
            to: "#echo_server",
        },

    ],
}

请注意,echo-server 实例来自与集成测试相同的软件包。此做法通过避免依赖于其他软件包的组件,来提升封闭的测试软件包。

将以下规则添加到 BUILD.bazel 文件中,以便将集成测试组件添加到 build 配置中:

echo-integration/BUILD.bazel

load(
    "@rules_fuchsia//fuchsia:defs.bzl",
    "fuchsia_cc_test",
    "fuchsia_component_manifest",
    "fuchsia_test_component",
    "fuchsia_test_package",
)

fuchsia_cc_test(
    name = "echo_integration_test",
    size = "small",
    srcs = ["echo_integration_test.cc"],
    deps = [
        "//fuchsia-codelab/echo-fidl:examples.routing.echo.fidl_cc",
        "@com_google_googletest//:gtest_main",
        "@fuchsia_sdk//pkg/async-default",
        "@fuchsia_sdk//pkg/async-loop",
        "@fuchsia_sdk//pkg/async-loop-cpp",
        "@fuchsia_sdk//pkg/async-loop-default",
        "@fuchsia_sdk//pkg/fdio",
        "@fuchsia_sdk//pkg/component_incoming_cpp",
        "@fuchsia_sdk//pkg/syslog",
    ],
)

fuchsia_component_manifest(
    name = "test_manifest",
    src = "meta/echo_integration_test.cml",
    component_name = "echo_integration_test_component",
    includes = [
        "@fuchsia_sdk//pkg/sys/testing:elf_test_runner",
        "@fuchsia_sdk//pkg/syslog:client",
    ],
)

fuchsia_test_component(
    name = "echo_integration_test_component",
    manifest = ":test_manifest",
    visibility = ["//visibility:public"],
    deps = [":echo_integration_test"],
)

fuchsia_test_package(
    name = "test_pkg",
    package_name = "echo_integration_test",
    visibility = ["//visibility:public"],
    components = [
        ":echo_integration_test_component",
        "//fuchsia-codelab/echo-server:echo_server_component",
    ],
)

实现集成测试

集成测试会连接到 echo-server 公开的 Echo 协议(与客户端组件相同),发送字符串请求,并验证预期响应。

添加以下代码以实现集成测试:

echo-integration/echo_integration_test.cc

#include <fidl/examples.routing.echo/cpp/fidl.h>
#include <gtest/gtest.h>
#include <lib/component/incoming/cpp/service_client.h>

#include <string>

TEST(EchoIntegrationTest, TestEcho) {
  zx::result client_end = component::Connect<examples_routing_echo::Echo>();
  ASSERT_TRUE(client_end.is_ok());
  fidl::SyncClient client{std::move(*client_end)};

  std::string request("Hello, world!");
  fidl::Result result = client->EchoString({request});
  ASSERT_TRUE(result.is_ok());

  auto response = result->response();
  ASSERT_TRUE(response.has_value());
  ASSERT_EQ(request, response.value());
}

更新 build 配置

构建集成测试软件包并将其发布到 fuchsiasamples.com 代码库:

bazel run //fuchsia-codelab/echo-integration:test_pkg.publish -- \
    --repo_name fuchsiasamples.com

运行集成测试

fuchsia_test_package() 规则会生成一个包含测试组件及其依赖项的软件包。集成测试组件的网址如下:

fuchsia-pkg://fuchsiasamples.com/echo_integration_test#meta/echo_integration_test.cm

使用 ffx test 命令执行集成测试。验证测试是否通过:

ffx test run \
    fuchsia-pkg://fuchsiasamples.com/echo_integration_test#meta/echo_integration_test.cm