測試 FIDL 通訊協定

必要條件

本教學課程是以 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 編寫。

設定依附元件

如何設定依附元件:

  1. 包含測試所需的程式庫:

    #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"
    
  2. 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" ]
    }
    
    

建立伺服器實作作業

如何建立伺服器實作:

  1. 新增要測試的 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_ 方法 會呼叫任何未覆寫的要求處理常式方法, 物件。

  2. 建立測試類別,納入發布 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() 方法,將 Proxy 初始化至目前的測試 並傳回該元件

新增測試

您可以使用測試固件編寫這項範例測試:

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);
}

執行測試

如何執行測試:

  1. 設定 GN 版本以納入測試:

    fx set core.x64 --with //examples/fidl/hlcpp/testing
  2. 執行測試:

    fx test -vo example-hlcpp-protocol-test

您應該會看到指出成功的測試輸出內容。

摘要

  • gtest::TestLoopFixture 不再需要使用樣板非同步迴圈 設定碼。每個測試案例只需呼叫 RunLoopUntilIdle() 即可,而不是 手動管理 async::Loop
  • ComponentContextProvider 可讓您輕鬆模擬元件結構定義 測試期間。舉例來說,並提供特定功能 元件
  • HLCPP 繫結測試 Scaffolding 可為各個通訊協定提供測試基礎 類別,其中每個方法都有預留位置實作。允許測試 以便只實作測試中的方法