使用 Buck2 构建 Rust Monorepo 单元测试

实现了 Monorepo 基本的编译能力后,开始探索使用 Buck2 的测试功能。看文档还是有点复杂,现在还不理解 Test Runner 这个概念,从表面上看是不是可以把 Docker 封装为一个 Test Runner,然后在 Buck2 中使用 Test Runner 运行测试?还是先把单元测试部分处理好吧...

首先是在在 toolchains 目录下的 BUCK 文件加入 remote_test_execution_toolchain 这个 Rule

load("@prelude//toolchains:remote_test_execution.bzl", "remote_test_execution_toolchain")

remote_test_execution_toolchain(
    name = "remote_test_execution",
    visibility = ["PUBLIC"],
)

在代码中加入测试用例,

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn version_match_works() {
        assert!(version_match("1.0.0", ">= 1.0.0"));
        assert!(version_match("1.0.0", ">= 1.0.0, < 2.0.0"));
        assert!(!version_match("1.0.0", ">= 2.0.0"));
    }
}

因为 rust_libraryrust_test 都要用相同的 deps, 所以在 rust_library 中加入 shared_deps 避免重复,感觉这个实现的方案也不优雅,但是还没有找到更合适的。

shared_deps = [
    "//third-party:semver",
]

rust_library(
    name = "rust-library",
    srcs = glob(["src/**/*.rs"]),
    crate_root = "src/lib.rs",
    tests = [
        "//projects/rust-library:rust-library-test",
    ],
    deps = shared_deps,
    visibility = ["PUBLIC"],
)

rust_test(
    name = "rust-library-test",
    srcs = glob(["src/**/*.rs"]),
    crate_root = "src/lib.rs",
    deps = shared_deps,
    visibility = ["PUBLIC"],
)

执行 buck2 test 命令进行测试,

$ buck2 test //...
✓ Pass: root//projects/rust-library:rust-library-test (0.0s)
---- STDOUT ----

running 1 test
test tests::version_match_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s


---- STDERR ----

Build ID: dbc61ebd-700f-49a4-8d33-28d5bd535051
Jobs completed: 4. Time elapsed: 0.0s.
Tests finished: Pass 1. Fail 0. Fatal 0. Skip 0. Build failure 0

Rust Monorepo Template with Buck2 中, 正在持续尝试构建一个完整的 Rust Monorepo 工程模板, 通过 Buck2Reindeer 管理整个工程的构建和测试, 可以从这个项目中开始你的 Rust Monorepo 之旅。