Skip to content

Add after-each test hook for hawk#47

Draft
iethree wants to merge 1 commit into
mainfrom
after-each
Draft

Add after-each test hook for hawk#47
iethree wants to merge 1 commit into
mainfrom
after-each

Conversation

@iethree

@iethree iethree commented Jun 11, 2026

Copy link
Copy Markdown

Adds an optional mb.hawk.hooks/after-each hook that runs arbitrary code after each test var, receiving that test's full output and report context, with zero overhead when no hooks are registered.

  • New after-each multimethod (mb.hawk.hooks) following the existing before-run/after-run convention. Hooks receive options and a context map: :var, :ns, :report-events (every clojure.test event, each tagged with its :testing-contexts), :output (captured out/err), :summary (pass/fail/error counts), :duration-ms, and :parallel?.
  • Zero-cost fast path: registration is checked once per run (after-each-hooks-registered?); with no hooks, run-test adds only a single dynamic-var deref per test — no output/event capture. Capture (a tee'd Writer + per-test event vector) is allocated only when a hook exists, and hooks run lock-free so ^:parallel tests stay concurrent.
  • Correct failure attribution: hooks fire just before a var's :end-test-var reaches the reporter, so a hook exception (or a clojure.test assertion inside a hook) is reported as an error/failure attributed to that var — counted in the summary and emitted as a proper element in the JUnit output.
  • No default after-each method (it would run once per test); a method on any dispatch value — including :default — enables the feature.
  • Adds README docs and tests covering context capture, failing/erroring tests, hook errors, JUnit attribution, the no-hook fast path, and output isolation across concurrent parallel tests.

@iethree iethree changed the title Add after-each test hook Add after-each test hook for hawk Jun 12, 2026
@iethree iethree requested a review from Copilot June 12, 2026 00:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an optional mb.hawk.hooks/after-each hook that runs after each individual clojure.test var, enabling consumers to run per-test side effects with access to captured output and report context while keeping a no-hook fast path.

Changes:

  • Introduces mb.hawk.hooks/after-each multimethod and after-each-hooks-registered? detection.
  • Extends the test runner to (optionally) capture per-test output + report events and invoke after-each before :end-test-var is reported.
  • Adds comprehensive tests and README documentation for the new per-test hook behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/mb/hawk/hooks.clj Adds the after-each hook multimethod and hook-registration detection helper.
src/mb/hawk/core.clj Implements the optional per-test capture + hook invocation path in the test-var runner.
test/mb/hawk/hooks_test.clj Adds tests validating context capture, error attribution, parallel behavior, and the no-hook fast path.
README.md Documents how to register and use after-each per-test hooks and the provided context keys.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/mb/hawk/hooks.clj
Comment on lines +83 to +85
If a hook throws (or a `clojure.test` assertion inside it fails), it is reported as a test error/failure attributed
to the test var -- it will fail the test suite and show up in the JUnit output -- and other after-each hooks for that
test may not run. Hooks run on the same thread as the test, so for `^:parallel` tests they may run concurrently.
Comment thread src/mb/hawk/hooks.clj
Comment on lines +95 to +99
dispatch value -- but you should probably make it a namespaced keyword to avoid conflicts, and give it a docstring so
people know why it's there. The orders the hooks are run in is indeterminate. The docstring for [[after-each]] is
updated automatically as new hooks are added; you can check it to see which hooks are in use. Note that hooks will
not be ran unless the namespace they live in is loaded; this may be affected by `:only` options passed to the test
runner.
(try
(do-with-after-each-hook
(fn [_options _context]
;; clojure.test attributes a report event to the var in (last *testing-vars*); verify it is still set
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.

2 participants