Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/py_test.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 6 additions & 17 deletions e2e/use_release/src/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@aspect_rules_py//py:defs.bzl", "py_binary", "py_pytest_main", "py_test")
load("@aspect_rules_py//py:defs.bzl", "py_binary", "py_test")

py_binary(
name = "main",
Expand All @@ -9,25 +9,14 @@ py_binary(
main = "__main__.py",
)

# TODO(alex): land https://github.com/aspect-build/rules_py/pull/401 and shorten this
py_pytest_main(
name = "__test__",
data = ["//:.coveragerc"],
deps = [
"@pip//coverage",
"@pip//pytest",
],
)

py_test(
name = "test",
srcs = [
"my_test.py",
":__test__",
],
main = ":__test__.py",
srcs = ["my_test.py"],
data = ["//:.coveragerc"],
pytest_main = True,
deps = [
":__test__",
":main",
"@pip//coverage", # keep
"@pip//pytest", # keep
],
)
56 changes: 9 additions & 47 deletions examples/pytest/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,75 +1,37 @@
load("@aspect_rules_py//py:defs.bzl", "py_library", "py_pytest_main", "py_test")
load("@aspect_rules_py//py:defs.bzl", "py_library", "py_test")

py_library(
name = "lib",
srcs = ["foo.py"],
imports = ["../.."],
)

py_pytest_main(
name = "__test__",
chdir = package_name(), # So that test fixtures are available at the correct path
deps = [
"@pypi_coverage//:pkg",
"@pypi_pytest//:pkg",
],
)

py_test(
name = "pytest_test",
srcs = [
"foo_test.py",
":__test__",
],
srcs = ["foo_test.py"],
data = glob([
"fixtures/*.json",
]),
env_inherit = ["FOO"],
imports = ["../.."],
main = ":__test__.py",
package_collisions = "warning",
pytest_main = True,
deps = [
":__test__",
":lib",
"@pypi_ftfy//:pkg",
"@pypi_neptune//:pkg",
"@pypi_pytest//:pkg",
],
)

py_test(
name = "nested/pytest",
srcs = [
"foo_test.py",
":__test__",
],
data = glob([
"fixtures/*.json",
]),
env_inherit = ["FOO"],
imports = ["../.."],
main = ":__test__.py",
package_collisions = "warning",
deps = [
":__test__",
":lib",
"@pypi_coverage//:pkg",
"@pypi_ftfy//:pkg",
"@pypi_neptune//:pkg",
"@pypi_pytest//:pkg",
],
)

py_test(
name = "sharding_test",
srcs = [
"__test__.py",
"sharding_test.py",
],
# NB: name contains a slash as regression test for #483
name = "sharded/test",
srcs = ["sharding_test.py"],
imports = ["../.."],
main = "__test__.py",
package_collisions = "warning",
pytest_main = True,
shard_count = 2,
deps = [
"__test__",
],
deps = ["@pypi_pytest//:pkg"],
)
6 changes: 4 additions & 2 deletions examples/pytest/foo_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import pytest
import json

import os

from examples.pytest.foo import add

def test_add():
assert add(1, 1) == 2, "Expected 1 + 1 to equal 2"

def test_hello_json():
content = open('fixtures/hello.json', 'r').read()
# NB: we don't use the chdir attribute so the test working directory is the repository root
content = open(os.path.join(os.getenv('TEST_TARGET').lstrip('/').split(':')[0], 'fixtures/hello.json'), 'r').read()
data = json.loads(content)
assert data["message"] == "Hello, world.", "Message is as expected"
16 changes: 14 additions & 2 deletions py/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def py_binary(name, srcs = [], main = None, **kwargs):

_py_binary_or_test(name = name, rule = _py_binary, srcs = srcs, main = main, resolutions = resolutions, **kwargs)

def py_test(name, srcs = [], main = None, **kwargs):
def py_test(name, srcs = [], main = None, pytest_main = False, **kwargs):
"""Identical to [py_binary](./py_binary.md), but produces a target that can be used with `bazel test`.

Args:
Expand All @@ -127,6 +127,8 @@ def py_test(name, srcs = [], main = None, **kwargs):
Like rules_python, this is treated as a suffix of a file that should appear among the srcs.
If absent, then `[name].py` is tried. As a final fallback, if the srcs has a single file,
that is used as the main.
pytest_main: If set, generate a [py_pytest_main](#py_pytest_main) script and use it as the main.
The deps should include the pytest package (as well as the coverage package if desired).
**kwargs: additional named parameters to `py_binary_rule`.
"""

Expand All @@ -139,4 +141,14 @@ def py_test(name, srcs = [], main = None, **kwargs):
if resolutions:
resolutions = resolutions.to_label_keyed_dict()

_py_binary_or_test(name = name, rule = _py_test, srcs = srcs, main = main, resolutions = resolutions, **kwargs)
deps = kwargs.pop("deps", [])
if pytest_main:
if main:
fail("When pytest_main is set, the main attribute should not be set.")
pytest_main_target = name + ".pytest_main"
main = pytest_main_target + ".py"
py_pytest_main(name = pytest_main_target)
srcs.append(main)
deps.append(pytest_main_target)

_py_binary_or_test(name = name, rule = _py_test, srcs = srcs, deps = deps, main = main, resolutions = resolutions, **kwargs)
9 changes: 7 additions & 2 deletions py/private/pytest.py.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import os
from pathlib import Path
from typing import List

import pytest
try:
import pytest
except ModuleNotFoundError as e:
print("ERROR: pytest must be included in the deps of the py_pytest_main or py_test target")
raise e

# None means coverage wasn't enabled
cov = None
# For workaround of https://github.com/nedbat/coveragepy/issues/963
Expand All @@ -37,7 +42,7 @@ if "COVERAGE_MANIFEST" in os.environ:
coveragepy_absfile_mapping = {coverage.files.abs_file(mfe): mfe for mfe in manifest_entries}
cov.start()
except ModuleNotFoundError as e:
print("WARNING: python coverage setup failed. Do you need to include the 'coverage' library as a dependency of py_pytest_main?", e)
print("WARNING: python coverage setup failed. Do you need to include the 'coverage' package as a dependency of py_pytest_main?", e)
pass

from pytest_shard import ShardPlugin
Expand Down