本文件將針對 GN 中 FIDL 測試的定義和整理方式進行標準化 建構系統,遵循下列目標:
- 一致的名稱。如果 Rust 使用
fx test fidl_rust_conformance_tests
, 接著,Go 應使用fx test fidl_go_conformance_tests
。一致且 且可預測的命名方式有助於提升開發人員體驗。 - 執行所需工作。測試工作流程應該要能讓您輕鬆執行 只需一個測試元件即可,不必另外建構或執行任何額外項目。
- 在主機上執行。應盡可能在主機上執行測試
- 遵循最佳做法。我們應該遵循 Fuchsia 的最佳做法
使用
fx test
, 建構元件等
術語
本文件使用下列術語:
- target:BUILD.gn 檔案中定義的 GN 目標
- toolchain:請參閱
fx gn help toolchain
- host:開發人員的平台,尤其是 Linux 或 mac
- device:Fuchsia 平台,實體或模擬 (例如 qemu)
- package:Fuchsia 套件;分配單位 紫紅色
- 元件:Fuchsia 元件;可執行軟體的單位 紫紅色
命名
一般指南:
- 請使用底線,而非連字號。
- 結尾的名稱為複數
_tests
,而非單數_test
。 - 為套件、元件和二進位檔使用完整且描述性的名稱。
最後重點是指更偏好全名,例如 fidl_rust_conformance_tests
與比對相關的名稱 (例如 conformance_tests
) 相比這聽起來可能很冗長
重複「fidl」的冗餘和「rust」目錄、套件、元件和
二進位等級的資料。事實上,這些名稱不得重複
如此一來,就不會記住一些奇怪的規則
fidl-bindings-test
代表 Dart,fidl-test
代表 C。
名稱應採用以下配置,並以底線連接部分:
工具 [ bindings ] [ category [ subcategory ] ] 測試
其中 tool 是下列任一項目:
- fidl:支援 FIDL 執行階段
- fidlc:FIDL 編譯器前端
- fidlgen:FIDL 編譯器後端
- gidl、measure_tape 等:其他工具
其他部分如下:
- 繫結
- 下列其中一個值:c、cpp、cpp_wire、hlcpp、rust、go 或 飛鏢
- category、subcategory
- 範例類別:conformance、types、parser、lib
- 請「不要」使用:前端、後端、繫結 (工具) 區別這些元素)
階層
每個定義測試的 BUILD.gn 檔案都應包含 "tests"
群組:
group("tests") {
testonly = true
deps = [ ... ] # not public_deps
}
如果目錄結尾是「tests」,而 BUILD.gn 檔案僅定義 test
目標,群組應該與目錄名稱相符。例如:
foo_tests/BUILD.gn 可以使用 group("foo_tests")
。這樣即可啟用 GN 標籤
簡寫 //path/to/foo_tests
,相當於 //path/to/foo_tests:foo_tests
。
這些群組會匯總在「測試」中父項 BUILD.gn 檔案群組
目錄根層級的「測試」(適用於程式碼集的某部分,例如
src/lib/fidl/BUILD.gn) 應包含在 bundle/fidl/BUILD.gn 中。這樣一來,
fx set ... --with //bundles/fidl:tests
,用於在版本中加入所有 FIDL 測試。
(由於 //bundles/buildbot/core
包括
//bundles/fidl:tests
)。
二進位檔名稱
一般而言,測試二進位檔名稱是以目標名稱為基礎。舉例來說
test("some_tests") { ... }
目標會產生 some_tests
二進位檔。
不過,單一測試通常需要多個目標 (來源集、
不重複名稱的元件、套件等)因此,本例中的範例
文件會使用 some_tests_bin
等目標名稱,並覆寫二進位檔名稱
使用 output_name
參數:
test("some_tests_bin") {
output_name = "some_tests"
...
}
這也適用於 rustc_test
、go_test
等等。
裝置測試
假設有一個 :fidl_foo_tests_bin
目標,可產生 fidl_foo_tests
二進位檔案。如要將這個項目納入套件中,請使用 fuchsia_unittest_package
:
import("//build/components.gni")
fuchsia_unittest_package("fidl_foo_tests") {
deps = [ ":fidl_foo_tests_bin" ]
}
現在可以依套件名稱或元件名稱 (相同) 執行測試
只在 fx test fidl_foo_tests
。
每次測試都使用獨立的套件。如果互不相關的測試元件 同時執行其中一項測試,系統就會為整個套件 建議您只將多個測試元件組合成單一套件,前提是它們必須含有 建議同時進行測試,例如進行用戶端與伺服器整合測試詳情請見 複雜拓撲和整合測試。
如果在測試時需要任何元件功能、服務等
fuchsia_unittest_component
預設值,您必須編寫元件資訊清單檔案:
# BUILD.gn
import("//build/components.gni")
fuchsia_unittest_package("fidl_foo_tests") {
manifest = "meta/fidl_foo_tests.cml"
deps = [ ":fidl_foo_tests_bin" ]
}
# meta/fidl_foo_tests.cml
{
program: {
"binary": "bin/fidl_foo_tests"
},
use: [
{
protocol: [
"fuchsia.logger.LogSink", # some example services
"fuchsia.process.Launcher"
]
}
]
}
如要進一步瞭解套件和元件範本,請參閱建構 元件。
主機測試
假設有一個 :fidl_bar_tests_bin
目標,可產生 fidl_bar_tests
二進位檔案。我們必須確保 GN 位於 $host_toolchain
後
目標,否則會嘗試為 Fuchsia 建構:
groups("tests") {
testonly = true
deps = [ ":fidl_bar_tests_bin($host_toolchain)" ]
}
(一律將 ($host_toolchain)
加入 BUILD.gn 檔案的 tests
群組,而非
//bundles/fidl:tests.)
這會建立名為 host_x64/fidl_bar_tests
的 test_spec 項目。
結尾是 out/default/tests.json:
{
"command": [ "host_x64/fidl_bar_tests", "--test.timeout", "5m" ],
"cpu": "x64",
"label": "//PATH/TO/BAR:fidl_bar_tests_bin(//build/toolchain:host_x64)",
"name": "host_x64/fidl_bar_tests",
"os": "linux",
"path": "host_x64/fidl_bar_tests",
"runtime_deps": "host_x64/gen/PATH/TO/BAR/fidl_bar_tests_bin.deps.json"
}
由於「名稱」發生問題,因此執行 fx test fidl_bar_tests
後可正常運作欄位
tests.json.
主機/裝置測試
在主機和裝置上執行的測試分為兩種。第一個 類別,只是在工具鍊下建構測試目標。例如:
import("//build/components.gni")
rustc_test("fidl_rust_conformance_tests_bin") {
output_name = "fidl_rust_conformance_tests" # host test name
...
}
fuchsia_unittest_package("fidl_rust_conformance_tests") { # device test name
deps = [ ":fidl_rust_conformance_tests_bin" ]
}
group("tests") {
testonly = true
deps = [
":fidl_rust_conformance_tests_bin($host_toolchain)",
":fidl_rust_conformance_tests",
]
}
我們現在可以透過這兩種方式執行測試:
- 裝置端:
fx test fidl_rust_conformance_tests --device
- 在主機:
fx test fidl_rust_conformance_tests --host
在第二種類別中,裝置和主機測試會共用原始碼,但
這兩者之間會有極大的差異。這個
您需要在 if (is_host) { ... }
中包裝主機測試定義,
GN 抱怨多個目標產生相同結果。例如:
import("//build/components.gni")
source_set("conformance_test_sources") {
...
}
test("fidl_hlcpp_conformance_tests_bin") {
output_name = "fidl_hlcpp_conformance_tests"
...
deps = [
":conformance_test_sources",
...
]
}
if (is_host) {
test("fidl_hlcpp_conformance_tests_bin_host") {
output_name = "fidl_hlcpp_conformance_tests" # host test name
...
deps = [
":conformance_test_sources",
...
]
}
}
fuchsia_unittest_package("fidl_hlcpp_conformance_tests") { # device test name
deps = [ ":fidl_hlcpp_conformance_tests_bin" ]
}
group("tests") {
testonly = true
deps = [
":fidl_hlcpp_conformance_tests_bin_host($host_toolchain)",
":fidl_hlcpp_conformance_tests",
]
}
現在,我們可以用這兩種方式執行測試:
- 裝置端:
fx test fidl_hlcpp_conformance_tests --device
- 在主機:
fx test fidl_hlcpp_conformance_tests --host
Rust 單元測試
Rust 程式庫的定義方式如下:
rustc_library("baz") {
with_unit_tests = true
...
}
這會自動建立 baz_test
目標來建構 baz_lib_test
二進位檔案。不建議使用,原因如下:
請編寫具有獨立 rustc_test
目標的獨立 rustc_test
目標,而不是 with_unit_tests
適當名稱:
rustc_library("baz") {
...
}
rustc_test("fidl_baz_tests") {
...
}
分組方式
假設我們的測試結構如下:
- Rust 的 FIDL
- 裝置
- 合規
- 整合
- 代管者
- 合規
- 裝置
我們應該針對葉子設立測試目標:
fx test fidl_rust_conformance_tests
fx test fidl_rust_integration_tests
我們不應該另外建立其他套件,以便執行
測試。有了 fx test
,我們就能
- 執行所有測試:
fx test //path/to/fidl/rust
- 執行所有裝置測試:
fx test //path/to/fidl/rust --device
- 執行所有主機測試:
fx test //path/to/fidl/rust --host