Bazel测试C++ Gtest时如何为每个TEST_P参数创建独立沙箱?
Bazel TEST_P参数化测试独立保存沙箱内容的解决方案
Bazel默认对单个测试目标仅创建一个沙箱实例,所有TEST_P参数化用例是在同一个测试进程内顺序执行的,因此会共用同一个沙箱,产生内容覆盖问题,可通过以下两种方案解决:
方案1:无需修改测试代码,单独运行每个用例并独立存储沙箱
适合不想改动测试逻辑的场景,通过gtest过滤参数单独执行每个用例,每个用例对应独立的沙箱目录:
- 先获取所有TEST_P用例的完整名称
bazel test //test/directory:my_test --test_arg=--gtest_list_tests - 编写脚本遍历所有用例,每个用例单独执行并指定独立的沙箱根目录,示例bash脚本如下:
# 提取所有测试用例名 ALL_TESTS=$(bazel test //test/directory:my_test --test_arg=--gtest_list_tests 2>&1 | grep -E '^ [a-zA-Z0-9_./]+' | sed 's/^ //') for test_case in $ALL_TESTS; do # 替换用例名中的特殊字符为安全字符作为目录名 safe_case_name=$(echo "${test_case}" | tr '/.' '_') SAVE_DIR="./sandbox_outputs/${safe_case_name}" mkdir -p "${SAVE_DIR}" # 单独执行单条用例,指定独立沙箱根目录 bazel test //test/directory:my_test \ --sandbox_debug \ --sandbox_base="${SAVE_DIR}" \ --test_arg=--gtest_filter="${test_case}" done
运行完成后所有用例的沙箱内容会分别保存在sandbox_outputs下对应用例名的目录中。
方案2:修改测试代码主动持久化保存沙箱内容
适合不想重复执行测试的场景,直接在测试逻辑中将需要保留的内容按用例名保存到Bazel指定的未声明输出目录,无需多次运行测试:
- 在TEST_P逻辑中获取当前用例的唯一标识,将沙箱中需要留存的内容拷贝到
TEST_UNDECLARED_OUTPUTS_DIR环境变量对应的目录下,示例C++代码如下:#include <filesystem> #include <gtest/gtest.h> #include <string> #include <cstdlib> TEST_P(MyTestSuite, MyTestCase) { // 测试运行逻辑,产生需要保存的沙箱文件 std::string sandbox_content_path = "./runtime_output.tmp"; // 获取当前用例的唯一名称 const ::testing::TestInfo* current_test = ::testing::UnitTest::GetInstance()->current_test_info(); std::string case_unique_name = std::string(current_test->test_suite_name()) + "_" + current_test->name(); // 替换路径特殊字符 std::replace(case_unique_name.begin(), case_unique_name.end(), '/', '_'); std::replace(case_unique_name.begin(), case_unique_name.end(), '.', '_'); // 获取Bazel提供的未声明输出目录,该目录内容会被Bazel自动持久化 const char* output_dir = std::getenv("TEST_UNDECLARED_OUTPUTS_DIR"); std::string save_path = std::string(output_dir) + "/" + case_unique_name + "_output.tmp"; // 拷贝沙箱文件到持久化目录 std::filesystem::copy(sandbox_content_path, save_path); } - 运行测试时添加
--test_output=all参数保证输出完整,运行完成后所有用例的留存文件可以在bazel-testlogs/test/directory/my_test/test.outputs/undeclared_outputs/目录下找到。
内容的提问来源于stack exchange,提问作者FressenUndFurzen
相关产品推荐
相关产品推荐

