bazel test与pytest框架的对接

python下常用的测试框架有两个:

  • unittest
  • pytest

最近有刚好在鼓捣bazel test,bazel test可以无缝对接unittest框架,但是在对接pytest框架时却存在一些问题,现将一些注意事项总结一下。

本片主要参考这篇[*的回答](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

上一篇:关于BRPC的入坑指南


下一篇:源码编译tensorflow