Bazel + Python unit testing: macro design, dep granularity, and pytest bootstrap patterns #2867
Replies: 2 comments
-
1. Should a unit test macro exist at all?Yes — keep it, keep it thin. The macro wires up exactly the ceremony every test author would otherwise duplicate: The risk of an implicit contract is manageable: the macro is ~50 lines, has no conditional logic or plugin injection, and anyone who needs something it doesn't support falls back to raw Why not reuse
The Long-term, the right move might be to contribute a more configurable 2. Dep granularity vs. maintenance costThe For sustainability:
3. Pytest bootstrap patternThe
The current approach matches what Bottom lineThe PR's approach is sound across all three questions. The macro is justified as long as it stays thin. The |
Beta Was this translation helpful? Give feedback.
-
|
We align with all three points raised here. We have documented the design decisions in a Decision Record following the Eclipse S-CORE DR convention:
The DR covers the macro design (dedicated |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
We are building a unit test infrastructure on top of rules_python and py_test for a project that also has a heavier integration test
framework (py_itf_test). A concrete example of what we have so far is in this PR: eclipse-score/itf#94
We'd like to hear how others approach three recurring design questions.
We introduced a py_itf_unittest macro (https://github.com/eclipse-score/itf/pull/94/files#diff-...) as a thin wrapper around py_test that
sets up pytest, injects pytest-mock, and provides a default pytest.ini. The alternative is to have test authors call py_test directly and
declare their pytest dep explicitly.
The macro adds convenience and consistency, but it hides what is actually happening and creates an implicit contract with macro consumers.
How do others draw this line? Is a macro justified, or does it create more problems than it solves as the project grows?
For unit tests to be truly atomic, each test target should only depend on the specific module it exercises. In practice this means
splitting coarse Bazel targets. For example, we split //score/itf/plugins/qemu into :config (just config.py + pydantic) and :qemu (the
full plugin) — visible in https://github.com/eclipse-score/itf/pull/94/files. This keeps the coverage denominator honest and avoids
pulling unrelated code into the test sandbox.
The tension is maintenance: as the codebase grows, keeping Bazel targets fine-grained requires discipline. What strategies do others use?
Do you enforce granularity via linting/visibility rules, or accept coarser targets and live with the coverage noise?
Both our macro and score_py_pytest from @score_tooling use a shared main.py that calls pytest.main(args) as the py_test entry point. This
works, but it is a workaround — py_test expects a unittest-style entry point, not a pytest runner.
Is there a community-standard way to run pytest as a py_test target in Bazel? Should this come from rules_python directly? We are aware of
third-party solutions but curious whether there is an emerging standard or a direction from the rules_python maintainers.
For more context on our setup, see the full PR: eclipse-score/itf#94. Interested in how others have solved these.
Happy to share more details.
Beta Was this translation helpful? Give feedback.
All reactions