前提条件
本教程基于 HLCPP 入门教程。
概览
本教程详细介绍了
Echo.EchoString
方法结合使用。本教程介绍了如何使用这两个实用程序
可用于测试在 HLCPP 中实现的 FIDL 协议:
gtest
测试循环夹具sys::testing::ComponentContextProvider
。- HLCPP 绑定提供的
fidl_test_base.h
文件
如果要自行编写代码,请删除以下目录:
rm -r examples/fidl/hlcpp/testing/*
测试将采用 examples/fidl/hlcpp/testing/main.cc
编写。
设置依赖项
如需设置依赖项,请执行以下操作:
添加测试所需的库:
#include <fuchsia/examples/cpp/fidl.h> #include <fuchsia/examples/cpp/fidl_test_base.h> #include <lib/fidl/cpp/binding.h> #include <lib/sys/cpp/testing/component_context_provider.h> #include "src/lib/testing/loop_fixture/test_loop_fixture.h"
在
examples/fidl/hlcpp/testing/BUILD.gn
中为测试添加构建规则:# Copyright 2020 The Fuchsia Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import("//build/components.gni") executable("bin") { testonly = true output_name = "example_hlcpp_protocol_test" sources = [ "main.cc" ] deps = [ "//examples/fidl/fuchsia.examples:fuchsia.examples_hlcpp", "//sdk/lib/fidl/hlcpp", "//sdk/lib/sys/cpp", "//sdk/lib/sys/cpp/testing:unit", "//src/lib/fxl/test:gtest_main", "//src/lib/testing/loop_fixture", ] } fuchsia_unittest_package("example-hlcpp-protocol-test") { deps = [ ":bin" ] } group("hermetic_tests") { testonly = true deps = [ ":example-hlcpp-protocol-test" ] }
创建服务器实现
如需创建服务器实现,请执行以下操作:
为被测试的
Echo
协议添加实现:class EchoImpl : public fuchsia::examples::testing::Echo_TestBase { public: void EchoString(std::string value, EchoStringCallback callback) override { callback(value); } void NotImplemented_(const std::string& name) override { std::cout << "Not implemented: " << name << std::endl; } };
此实现不是继承自
fuchsia::examples::Echo
,而是继承了 继承自相应的测试基类。这意味着 实现只需替换正在测试的方法 (本例中为EchoString
)以及NotImplemented_
方法,该方法用于 如果任何未替换的请求处理程序方法 调用。创建一个测试类,用于封装发布 echo 协议的逻辑:
class EchoServerInstance { public: explicit EchoServerInstance(std::unique_ptr<sys::ComponentContext> context) { context_ = std::move(context); binding_ = std::make_unique<fidl::Binding<fuchsia::examples::Echo>>(&impl_); fidl::InterfaceRequestHandler<fuchsia::examples::Echo> handler = [&](fidl::InterfaceRequest<fuchsia::examples::Echo> request) { binding_->Bind(std::move(request)); }; context_->outgoing()->AddPublicService(std::move(handler)); } private: EchoImpl impl_; std::unique_ptr<fidl::Binding<fuchsia::examples::Echo>> binding_; std::unique_ptr<sys::ComponentContext> context_; };
该代码类似于 服务器教程,但
fidl::Binding
归类所有。 这样,系统就会在销毁类时调用绑定的析构函数。 这样,代码就可以在给定的每个测试用例上发布 echo 协议 测试组件上下文的新实例。
实现测试固件类
class EchoTestFixture : public gtest::TestLoopFixture {
public:
void SetUp() override {
TestLoopFixture::SetUp();
echo_instance_.reset(new EchoServerInstance(provider_.TakeContext()));
}
void TearDown() override {
TestLoopFixture::TearDown();
echo_instance_.reset();
}
protected:
fuchsia::examples::EchoPtr GetProxy() {
fuchsia::examples::EchoPtr echo;
provider_.ConnectToPublicService(echo.NewRequest());
return echo;
}
private:
std::unique_ptr<EchoServerInstance> echo_instance_;
sys::testing::ComponentContextProvider provider_;
};
测试夹具会执行以下操作:
- 存储
ComponentContextProvider
的实例。每次测试时,它都会使用 创建一个新的测试上下文,并使用EchoServerInstance
类。 - 提供
GetProxy()
方法,用于初始化当前测试的代理 组件上下文,并返回该上下文。
添加测试
您可以使用测试固件编写下面的测试示例:
TEST_F(EchoTestFixture, EchoString) {
fuchsia::examples::EchoPtr proxy = GetProxy();
bool received_response = false;
proxy->EchoString("hello there", [&](std::string response) {
ASSERT_EQ(response, "hello there");
received_response = true;
});
proxy.set_error_handler(
[](zx_status_t status) { ASSERT_TRUE(false && "should not throw any errors"); });
RunLoopUntilIdle();
EXPECT_TRUE(received_response);
}
运行测试
如需运行测试,请执行以下操作:
配置您的 GN build 以包含该测试:
fx set core.x64 --with //examples/fidl/hlcpp/testing
运行测试:
fx test -vo example-hlcpp-protocol-test
您应该会看到测试输出,表明测试成功。
摘要
gtest::TestLoopFixture
不再需要样板异步循环 设置代码。每个测试用例只需调用RunLoopUntilIdle()
,而不是 手动管理async::Loop
。ComponentContextProvider
可让您轻松模拟组件上下文 。这对于以下情形非常有用:为容器提供特定功能 组件。- HLCPP 绑定测试基架为每个协议提供了一个测试库 类,其中包含每个方法的占位符实现。这样,测试 仅实现被测方法。