Skip to content

feat: attribute Pact logs to each test - #1731

Draft
JP-Ellis wants to merge 3 commits into
feat/logging-forwardingfrom
feat/logging-test-run-id
Draft

JP-Ellis wants to merge 3 commits into
feat/logging-forwardingfrom
feat/logging-test-run-id

Conversation

@JP-Ellis

@JP-Ellis JP-Ellis commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

✈️ Pre-flight checklist

  • I have read the Contributing Guidelines on pull requests.
  • If this is a code change: I have written unit tests and/or added dogfooding pages to fully verify the new behavior.
  • If this is a new API or substantial change: the PR has an accompanying issue (closes #0000) and the maintainers have approved on my working plan.

📝 Summary

Attributes Pact log records to the test which caused them, with no set-up in user code.

  • A pytest plugin, registered through the pytest11 entry point, sets each test's node ID as the Pact test run ID for the duration of the test. -p no:pact disables it.
  • pact.testing.unittest provides a mixin which does the same for unittest test cases. It also writes the test's Pact records to stderr when the test fails or errors.
  • The logging docs describe both.

Stacked on #1730.

🔥 Motivation

The forwarded records carry test_run_id, but only when something sets it. An autouse fixture covers every pytest suite by default. An opt-in fixture would need every project to remember the set-up.

🔨 Test Plan

  • pytester runs a small suite and checks the run ID is set and cleared per test, and that -p no:pact disables the plugin.
  • The mixin is exercised through unittest.TestResult. Its tests check that output appears only on failure and error, and that the handler is removed afterwards.

🔗 Related issues/PRs

Register a pytest plugin through the pytest11 entry point with one
autouse fixture, pact_test_run_id, which sets the node ID as the Pact
test run ID for the test's duration. Log records from the library and
from plugins then name the test which caused them without any conftest
set-up.

An autouse fixture rather than a documented one, because opting in
would require every test suite to remember the set-up; disabling it is
a single `-p no:pact` instead.

Signed-off-by: JP-Ellis <josh@jpellis.me>
Assisted-by: Claude Code:claude-opus-5-5
unittest has no plugin entry point and no log capture on failure, so
PactTestMixin wraps run() to set the test ID as the Pact test run ID,
buffer records on the pact logger, and print them to stderr when the
test fails or errors.

A logger hands a record to its handlers only when the record clears the
logger's effective level, and outside pytest that level is the root
logger's WARNING. The mixin therefore lowers the pact logger to the
forwarding level while the test runs, when the logger has no explicit
level of its own, and restores it afterwards.

Signed-off-by: JP-Ellis <josh@jpellis.me>
Assisted-by: Claude Code:claude-opus-5
Add the pytest and unittest integrations to the logging page, under
correlating logs with tests, and point the pact.logging module
docstring at them.

Fix cross-reference syntax in src/pact/testing/{__init__,pytest,
unittest}.py: `mkdocs build --strict` reported them unresolved.
mkdocstrings' scoped_crossrefs prepends the package prefix again to a
`pact.`-prefixed target from a module below the package root, so
cross-module references use the path relative to the `pact` package.

Signed-off-by: JP-Ellis <josh@jpellis.me>
Assisted-by: Claude Code:claude-opus-5-5
@JP-Ellis
JP-Ellis added this pull request to stack #1733 October 16, 2026 00:37
@JP-Ellis JP-Ellis changed the title feat/logging test run id feat: attribute Pact logs to each test Oct 16, 2026
@JP-Ellis JP-Ellis mentioned this pull request Oct 16, 2026
2 of 3 tasks

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant