如何在Bazel中对源码树执行测试?CMake转Bazel项目测试配置问题
解决Bazel中收集Python文件(含genrule输出)作为测试依赖的问题
我碰到过不少从CMake迁移到Bazel的开发者遇到这类问题——想给测试脚本收集所有.py文件,但目录里的BUILD文件、genrule生成的文件让简单的glob不好用。下面给你几个针对性的方案:
1. 精准捕获源Python文件,排除无关文件
如果你的需求是先拿到所有手写的Python源文件(避免误引入BUILD相关干扰,虽然BUILD不是.py后缀,但子目录的BUILD文件所在路径下的py文件没问题,保险起见可以过滤),可以给glob加上排除规则:
glob( ["**/*.py"], exclude=["**/BUILD", "**/BUILD.bazel"], )
这样就能准确获取到所有你自己写的.py文件,不会被目录里的BUILD文件(哪怕是子目录里的)影响。
2. 纳入genrule生成的Python文件
如果测试脚本还需要依赖genrule生成的.py文件,那单纯的源文件glob就不够了——因为genrule的输出默认在Bazel的输出目录(bazel-out)里,不会被源目录的glob捕获。这时候要分两步走:
- 先给genrule的输出定义一个明确的目标,比如:
genrule( name = "generated_py_files", srcs = [...], # 你的genrule依赖源文件 outs = ["generated/test_b.py"], # 生成的Python文件路径 cmd = "...", # 你的生成命令 ) - 然后把这个genrule目标和源文件glob一起加到测试脚本的
data依赖中:py_test( name = "all_python_tests", srcs = ["test_runner.py"], # 你的测试执行脚本 data = [ ":generated_py_files", glob(["**/*.py"], exclude=["**/BUILD", "**/BUILD.bazel", "test_runner.py"]), ], )
这样测试运行时就能同时访问到源Python文件和生成的Python文件了。
3. 用filegroup统一管理所有Python资源
如果你的目录结构复杂,有多个genrule、多层子目录,建议用filegroup把所有需要的Python文件(源+生成)打包成一个复用目标:
filegroup( name = "all_python_sources", srcs = [ glob(["**/*.py"], exclude=["**/BUILD", "**/BUILD.bazel"]), ":generated_py_files", # 后续新增的genrule生成文件目标都可以加在这里 ], ) py_test( name = "all_python_tests", srcs = ["test_runner.py"], data = [":all_python_sources"], )
这样后续维护起来更方便,新增文件或genrule时只需要更新all_python_sources,不用修改测试目标的配置。
几个关键提醒
- Bazel的
glob默认只匹配工作区里的源文件,生成文件(比如genrule的outs)必须显式添加到依赖中,不会被glob自动捕获。 - 如果你的测试脚本是递归遍历运行测试文件,记得用Bazel提供的
$(location)宏来获取文件的正确路径,避免运行时找不到文件的问题。
内容的提问来源于stack exchange,提问作者edward_mj
相关产品推荐
相关产品推荐

