python下常用的测试框架有两个:
- unittest
- pytest
最近有刚好在鼓捣bazel test,bazel test可以无缝对接unittest框架,但是在对接pytest框架时却存在一些问题,现将一些注意事项总结一下。
本片主要参考这篇[stackoverflow的回答](python - How do I use pytest with bazel? - Stack Overflow)
方法一
很简单,将test_xxx.py中的启动代码由
if __name__ = __main__:
pytest.main()
修改为
if __name__ = __main__:
raise SystemExit(pytest.main([__file__]))
此方法较为简单,但是test文件夹中的每一个test__xxx文件都得做这样的修改,较为麻烦。
方法二
参考这篇博客,我们忽略pylint的部分,只引用pytest相关的部分。具体原理为,我们自己创建一个bazel rule,用来包裹我们的测试case。
1.在项目目录下创建src/pytest/
,目录内包含三个文件:
- BUILD
- defs.bzl
- pytest_wrapper.py
其中:
BUILD
exports_files([
"pytest_wrapper.py",
])
defs.bzl
"""Wrap pytest"""
load("@rules_python//python:defs.bzl", "py_test")
load("@deps//:requirements.bzl", "requirement")
def pytest_test(name, srcs, deps = [], args = [], data = [], **kwargs):
"""
Call pytest
"""
py_test(
name = name,
srcs = [
"//src/pytest:pytest_wrapper.py",
] + srcs,
main = "//src/pytest:pytest_wrapper.py",
args = [
"--capture=no",
] + args + ["$(location :%s)" % x for x in srcs],
python_version = "PY3",
srcs_version = "PY3",
deps = deps + [
requirement("pytest"),
],
data = data,
**kwargs
)
pytest_wrapper.py
import sys
import pytest
# if using 'bazel test ...'
if __name__ == "__main__":
sys.exit(pytest.main(sys.argv[1:]))
在test
文件夹中的BUILD文件内引用pytest_test rule即可。
test/BUILD
load("//src/pytest:defs.bzl", "pytest_test")
pytest_test(
name = "test_larry",
srcs = ["test_larry.py"],
imports = ["../larry/"],
deps = [
"//larry:larry",
],
)
详情可参见github:bazel_python_demo