整合測試

整合測試著重於驗證元件與系統其他元件互動時的行為。因此,整合測試通常與主要元件分開建構,而且可能會將受測元件和其他依附元件宣告為子項。視測試的性質而定,依附元件元件可以做為模擬或虛設常式提供,以提倡測試情況是否保持不變。

測試元件

以下是簡易整合測試元件的元件資訊清單範例:

Rust

meta/integration_tests.cml:

{
    include: [
        "syslog/client.shard.cml",
        "//src/sys/test_runners/rust/default.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" ],
        },
    ],
}

C++

meta/integration_tests.cml:

{
    include: [
        "syslog/client.shard.cml",
        "//src/sys/test_runners/gtest/default.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 建構系統針對不同的測試元件 (例如整合測試) 提供 fuchsia_test_package() GN 目標。這項規則可讓您單獨宣告內含測試的元件,而非做為依附元件的元件,並描述應執行測試的目標裝置環境。

以下範例說明如何在 BUILD.gn 檔案中納入上述整合測試:

import("//build/components.gni")
...

// Component under test
fuchsia_component("foo_client") {
  deps = [ ... ]
  manifest = "meta/foo_client.cml"
}

// Test dependencies
fuchsia_component("mock_service") {
  deps = [ ... ]
  manifest = "meta/mock_service.cml"
  testonly = true
}

// Component containing integration tests
fuchsia_component("integration_tests") {
  deps = [ ":bin_test" ]
  manifest = "meta/integration_tests.cml"
  testonly = true
}

fuchsia_test_package("hello-world-tests") {
  test_components = [ ":integration_tests" ]
  deps = [
    ":foo_client",
    ":mock_service",
  ]
}

練習:Echo 伺服器整合測試

在本練習中,您將新增整合測試元件,以透過測試執行器架構執行 echo_server 元件的 FIDL 通訊協定介面,並在 FEMU 環境中執行這些測試。

新增整合測試元件

首先,請在 //vendor/fuchsia-codelab 目錄中為名為 echo-integration 的新整合測試元件建立專案鷹架:

mkdir -p vendor/fuchsia-codelab/echo-integration

在新專案目錄中建立以下檔案和目錄結構:

Rust

echo-integration
  |- BUILD.gn
  |- meta
  |   |- echo_integration.cml
  |
  |- src
      |- lib.rs
  • BUILD.gn:測試二進位檔、元件和套件的 GN 建構目標。
  • meta/echo_integration.cml:資訊清單,宣告受測試的元件及其功能。
  • src/lib.rs:Rust 整合測試的原始碼。

C++

echo-integration
  |- BUILD.gn
  |- meta
  |   |- echo_integration.cml
  |
  |- echo_integration_test.cc
  • BUILD.gn:測試二進位檔、元件和套件的 GN 建構目標。
  • meta/echo_integration.cml:資訊清單,宣告受測試的元件及其功能。
  • echo_integration_test.cc:C++ 整合測試的原始碼。

更新測試元件資訊清單

測試元件的資訊清單會套用基準依附元件,例如 test_runners。更新 echo_integration.cml 檔案,將 echo-server 元件宣告為子項,並將 Echo 通訊協定能力轉送至測試元件。

Rust

echo-integration/meta/echo_integration.cml:

{
    include: [
        "//src/sys/test_runners/rust/default.shard.cml",
        "syslog/client.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: [ "fidl.examples.routing.echo.Echo" ],
            from: "#echo_server",
        },
    ],

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

C++

echo-integration/meta/echo_integration.cml:

{
    include: [
        "//src/sys/test_runners/gtest/default.shard.cml",
        "syslog/client.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: [ "fidl.examples.routing.echo.Echo" ],
            from: "#echo_server",
        },
    ],

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

請注意,echo-server 執行個體來自與整合測試相同的套件。這項做法避免透過避免其他套件的元件依附元件,宣傳具有「密封式」的測試套件。

實作整合測試

整合測試會連線至 echo-server 公開的 Echo 通訊協定,方法與用戶端元件相同、傳送字串要求,並驗證預期回應。

新增下列程式碼即可實作整合測試:

Rust

echo-integration/src/lib.rs:

use {anyhow::Error, fidl_fidl_examples_routing_echo as fecho, fuchsia_component::client};

#[fuchsia::test]
async fn echo_integration_test() -> Result<(), Error> {
    const ECHO_STRING: &str = "Hello, world!";

    let echo = client::connect_to_protocol::<fecho::EchoMarker>()
        .expect("error connecting to echo server");
    let out = echo.echo_string(Some(ECHO_STRING)).await.expect("echo_string failed");

    assert_eq!(ECHO_STRING, out.unwrap());
    Ok(())
}

C++

echo-integration/echo_integration_test.cc:

#include <fidl/examples/routing/echo/cpp/fidl.h>
#include <lib/fidl/cpp/string.h>
#include <lib/sys/cpp/component_context.h>

#include <string>

#include <gtest/gtest.h>

TEST(EchoIntegrationTest, TestEcho) {
  ::fidl::examples::routing::echo::EchoSyncPtr echo_proxy;
  auto context = sys::ComponentContext::Create();
  context->svc()->Connect(echo_proxy.NewRequest());

  ::fidl::StringPtr request("Hello, world!");
  ::fidl::StringPtr response = nullptr;
  ASSERT_TRUE(echo_proxy->EchoString(request, &response) == ZX_OK);
  ASSERT_TRUE(request == response);
}

將下列建構規則新增至 BUILD.gn 檔案,以建構整合測試元件及 echo 伺服器依附元件並套件:

Rust

echo-integration/BUILD.gn:

import("//build/components.gni")
import("//build/rust/rustc_test.gni")


rustc_test("bin") {
  name = "echo-integration-test"
  edition = "2021"

  deps = [
    "//vendor/fuchsia-codelab/echo-fidl:echo_rust",
    "//src/lib/fuchsia",
    "//src/lib/fuchsia-component",
    "//third_party/rust_crates:anyhow",
  ]

  sources = [ "src/lib.rs" ]
}

fuchsia_component("component") {
  testonly = true
  component_name = "echo_integration"
  manifest = "meta/echo_integration.cml"
  deps = [ ":bin" ]
}

fuchsia_test_package("tests") {
  package_name = "echo-integration-tests"
  test_components = [ ":component" ]
  deps =
      [ "//vendor/fuchsia-codelab/echo-server:component" ]
}

C++

echo-integration/BUILD.gn:

import("//build/components.gni")


executable("bin") {
  output_name = "echo-integration-test"
  sources = [ "echo_integration_test.cc" ]
  deps = [
    "//vendor/fuchsia-codelab/echo-fidl:echo_hlcpp",
    "//sdk/lib/sys/cpp",
    "//sdk/lib/sys/cpp/testing:unit",
    "//src/lib/fxl/test:gtest_main",
    "//third_party/googletest:gtest",
    "//zircon/system/ulib/async-loop:async-loop-cpp",
    "//zircon/system/ulib/async-loop:async-loop-default",
  ]
  testonly = true
}

fuchsia_component("component") {
  testonly = true
  component_name = "echo_integration"
  manifest = "meta/echo_integration.cml"
  deps = [ ":bin" ]
}

fuchsia_test_package("tests") {
  package_name = "echo-integration-tests"
  test_components = [ ":component" ]
  deps =
      [ "//vendor/fuchsia-codelab/echo-server:component" ]
}

更新建構設定

將整合測試套件新增至建構設定:

fx set workstation_eng.x64 \
    --with //vendor/fuchsia-codelab/echo-server \
    --with //vendor/fuchsia-codelab/echo-client \
    --with //vendor/fuchsia-codelab/echo-realm \
    --with //vendor/fuchsia-codelab/echo-integration:tests

執行 fx build,並確認建構作業已成功完成:

fx build

執行整合測試

fuchsia_test_package() 規則會產生含有測試元件及其依附元件的套件。整合測試元件的下列網址如下:

fuchsia-pkg://fuchsia.com/echo-integration-tests#meta/echo_integration.cm

使用 ffx test 指令執行整合測試。確認測試是否通過:

ffx test run \
    fuchsia-pkg://fuchsia.com/echo-integration-tests#meta/echo_integration.cm