--watch that only reruns tests affected by loaded changes #284
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a code sketch of a feature I've been desiring in a test runner:
when in watch mode, only rerun tests that have been affected by loaded changes
background
I wanted to do a proof-of-concept to prove it was generally possible (hence no tests yet :) ), and now I'm interested in discussing whether this is something kaocha folks would be interested in including. If so, does my general approach look okay (modulo the
TODO
s) or do I need to hook into different parts of the system?I imagine that it could be a different CLI flag, aside from
--watch
given that it might have (incompleteness) bugs; something like--watch-with-deps-analysis
(or something shorter if a good name arises)behavior
current
Currently in kaocha, with
--watch
, when a file changes, it is reloaded, along with its corresponding*_test.clj
friend. Then the entire test suite is re-run. Back when I worked at Nubank this could mean ~1-2 minutes of tests, and hence I never really used--watch
.There is the nice case where if tests fail, upon next code reload, those test failures are run first, and only if they pass are the rest of the tests run, which helps with the re-run times of the entire test suite.
proposed
With the changes in this PR, with
--watch
(or whatever new flag we give the behavior), when the suite runs for the first time it analyzes all loaded namespaces using Clerk's form hash/dependency analysis and stores the results in an atom. Then when a file changes, it is reloaded, along with its corresponding*_test.clj
friend. Right after reload, and before the tests are run, we re-analyze the changed namespaces using Clerk. If any forms change (via the calculated hash), we find all test forms that aredependents
of that changed form and pass them back to kaocha's filtering logic to ensure only they are run.For example, if I'm running kaocha in some random project like ordnungsamt
and I change only the
compose-filters
def, then only the test that usescompose-filters
, either directly or indirectly, is re-run:midje test runner
I used to use Midje a lot and got used to the way it did watching and test auto rerunning.
It wouldn't re-run the entire test suite on reloads, but rather only tests for namespaces that had to be reloaded. Note that namespace reloading for midje differs from kaocha in that changing a namespace would trigger reloading all depending namespaces. In effect, the midje test runner was sort of a middle ground between kaocha's current watch that re-runs everything and the behavior proposed in this PR that has a form level, instead of ns level, deps analysis that allows one to only rerun individual tests that were affected by reload changes.
for example, with
lein midje :autotest
on a random repository, changing a central/widely used namespace triggers a lot of other ns reloads and tests to run:but if you change a ns that doesn't isn't used by any other namespaces, it reloads and reruns fewer test
side note
this PR depends on this unmerged commit to Clerk: nextjournal/clerk@32ef18e