如何在Bazel测试中实现可写入的测试数据文件?
解决Bazel测试中修改测试数据文件的问题
问题原因
Bazel会将data字段指定的测试文件放在只读的runfiles目录中,因此无法以读写权限打开修改。根据Bazel测试规范,测试仅能写入TEST_TMPDIR环境变量指向的临时目录。
解决方案:用Shell脚本前置复制数据
无需在C测试代码中编写拷贝逻辑,可通过Shell脚本作为测试入口,自动将测试数据复制到TEST_TMPDIR后再运行C测试二进制。
步骤1:编写测试启动脚本
创建run_sample_test.sh文件:
#!/bin/bash # 确保临时目录下的测试数据目录存在 mkdir -p "$TEST_TMPDIR/test_data" # 复制测试数据到临时目录(适配Bazel默认runfiles路径) cp -r "$(dirname "$0")/../test_data"/* "$TEST_TMPDIR/test_data/" # 执行实际的C++测试二进制 exec "$(dirname "$0")/sample_test_bin" "$@"
步骤2:修改BUILD文件
将原cc_test拆分为cc_binary(测试核心逻辑)和sh_test(负责前置数据复制):
filegroup( name = "test_data", srcs = glob(["test_data/*"]), ) # 编译测试核心逻辑为独立二进制文件 cc_binary( name = "sample_test_bin", srcs = ["sample_test.cc"], deps = [ # 保留原有的依赖,比如googletest "@com_google_googletest//:gtest_main", # 其他业务依赖... ], ) # 用Shell脚本包装测试,自动完成数据复制流程 sh_test( name = "sample_test", srcs = ["run_sample_test.sh"], data = [ ":sample_test_bin", ":test_data", ], # 可选:传递gtest过滤参数 # args = ["--gtest_filter=SampleTest.ModifyDataFile"], )
步骤3:调整C++测试代码的文件路径
在sample_test.cc中,从TEST_TMPDIR路径打开可读写的测试文件:
#include <cstdlib> #include <fstream> #include <string> #include <gtest/gtest.h> TEST(SampleTest, ModifyDataFile) { const char* tmp_dir = std::getenv("TEST_TMPDIR"); ASSERT_TRUE(tmp_dir != nullptr); std::string file_path = std::string(tmp_dir) + "/test_data/your_test_file.txt"; // 以读写权限打开文件 std::fstream data_file(file_path, std::ios::in | std::ios::out); ASSERT_TRUE(data_file.is_open()); // 执行修改操作示例 data_file << "updated test content"; data_file.seekg(0); std::string content; std::getline(data_file, content); EXPECT_EQ(content, "updated test content"); }
进阶优化:适配复杂Runfiles结构
如果工作区结构复杂或使用Bazel远程执行,建议用Bazel官方runfiles工具定位文件,避免路径错误:
#!/bin/bash # 加载Bazel官方runfiles工具库 source "$(rlocation bazel_tools/tools/bash/runfiles/runfiles.bash)" # 替换为你的工作区名称 WORKSPACE_NAME="your_workspace_name" # 通过runfiles工具精准定位文件 TEST_DATA_SRC=$(rlocation "${WORKSPACE_NAME}/test_data") TEST_BIN=$(rlocation "${WORKSPACE_NAME}/sample_test_bin") # 复制数据到临时目录 mkdir -p "$TEST_TMPDIR/test_data" cp -r "$TEST_DATA_SRC"/* "$TEST_TMPDIR/test_data/" # 执行测试二进制 exec "$TEST_BIN" "$@"
内容的提问来源于stack exchange,提问作者Franciszek Malinka
相关产品推荐
相关产品推荐

