| load("@rules_python//python:defs.bzl", "PyInfo", "py_test") |
| |
| def _stringify(paths): |
| return repr(paths) |
| |
| def _pytest_runner_impl(ctx): |
| if len(ctx.attr.srcs) == 0: |
| fail("No test files specified.") |
| |
| expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args] |
| |
| runner = ctx.actions.declare_file(ctx.attr.name) |
| ctx.actions.write( |
| runner, |
| """ |
| if __name__ == "__main__": |
| import sys |
| import pytest |
| |
| args = ["-ra"] + %s + sys.argv[1:] + %s |
| |
| sys.exit(pytest.main(args))""" % (_stringify(expanded_args), _stringify([src.path for src in ctx.files.srcs])), |
| is_executable = True, |
| ) |
| |
| return [ |
| DefaultInfo( |
| files = depset([runner]), |
| runfiles = ctx.runfiles(ctx.files.data), |
| executable = runner, |
| ), |
| ] |
| |
| _pytest_runner = rule( |
| _pytest_runner_impl, |
| attrs = { |
| "srcs": attr.label_list( |
| allow_files = [".py"], |
| ), |
| "deps": attr.label_list( |
| providers = [ |
| PyInfo, |
| ], |
| ), |
| "args": attr.string_list( |
| default = [], |
| ), |
| "data": attr.label_list( |
| allow_empty = True, |
| allow_files = True, |
| ), |
| "python_version": attr.string( |
| values = ["PY2", "PY3"], |
| default = "PY3", |
| ), |
| }, |
| ) |
| |
| def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs): |
| runner_target = "%s-runner.py" % name |
| |
| _pytest_runner( |
| name = runner_target, |
| testonly = True, |
| srcs = srcs, |
| deps = deps, |
| args = args, |
| data = data, |
| python_version = python_version, |
| ) |
| |
| py_test( |
| name = name, |
| python_version = python_version, |
| srcs = srcs + [runner_target], |
| deps = deps, |
| main = runner_target, |
| legacy_create_init = False, |
| imports = ["."], |
| **kwargs |
| ) |