-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove snapshot files when a test file stops using snapshots #2623
Conversation
Test with crashing file Test with failing tests Test with test.failing() Test with skipped hooks Test with esmodule Test with t.try() Test with a fixed snapshot location Test with a test directory
Don't prune snapshots if any test or hook failed Crashes can hide snapshot assertions. Assertion failures can prevent hooks from running, hiding snapshot assertions. Could be more precise - check whether any hook actually was skipped because of a test failure. Unclear benefit, more complex. Don't prune if any hooks were skipped Don't prune if any tests marked .failing() Don't prune if the test file crashes
No. Non-representative is a good way of putting it.
Yea, sounds good. Nice spot!
I don't care about hook behavior, that'll go away within the next few months. |
Rethinking this, I believe I was mistaken (in some cases dangerously so) about most of the conditions I listed. In particular,
Using snapshot assertions with nondeterministic test execution (whether thrown exceptions, concurrent tl;dr: I'm going to pare this PR back to essentially the original spec ( |
@ninevra there might be some things worth exploring, even as a future work. What if we didn't automatically write new snapshots when you add a test? And per test decide whether to write the result, e.g. if a failing test is passing, then we don't update its snapshot. Or we don't write any snapshots when there is a test failure (in this case, a failing test passing is a failure). |
There was a CI-dependent test failure. I believe I've resolved it, but it revealed some interesting edge-case behavior. It''s not important, just kind of odd/cool. When running a test file with skipped tests in test('the time', t => {
t.snapshot(Date.now());
}
test('the time again', t => {
t.snapshot(Date.now());
} both snapshots pass in test('the time', t => {
t.snapshot(Date.now());
}
test.skip('the time again', t => {
t.snapshot(Date.now());
} the first snapshot fails. The manager in the second case isn't in updating mode, and so loads the existing snapshot from disk and compares against it, even though The new check for test('the time', t => {
t.snapshot(Date.now());
}
test('the time again', t => {
t.snapshot.skip(Date.now());
t.pass();
} the first snapshot passes (in (In CI, the third example fails also, because snapshot assertions that would record new snapshots in CI instead fail. Thus the CI-dependent test failure.) |
This reverts commit 2eaad19. skippedSnapshots better reflects the field's meaning, since it records whether any snapshot assertion has yet been skipped. This is different from skippingTests, which records whether any test will be skipped.
This is the most common case: a test that didn't use snapshots before and doesn't now.
Line number selection is and was done by throwing an error if both `--update-snapshots` and a line number range are passed. A second check was added at Runner.saveSnapshotState() in this PR. This duplicate check is not reachable in integration testing, and its value is negligible or negative.
Allows tests to run concurrently. Promotes fs-extra to top-level devdependency.
Tests were previously split to allow concurrency among fixtures and serial execution in individual fixtures. This is no longer necessary, since tests no longer need exclusive access to their fixtures.
This is probably redundant. Also asserts that snapshot files aren't falsely reported as non-updateable.
@novemberborn
Other than that, this should be ready for review. I've updated the header post to reflect the current state of the PR. |
@ninevra thank you for your work on this, I'm hoping to take a look at it within the next few days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manager in the second case isn't in updating mode, and so loads the existing snapshot from disk and compares against it, even though
--update-snapshots
was passed.
Is this a bug then?
Possible future work (issues which came up in this process but are out-of-scope here):
Could you open issues so we can discuss these further?
One more thought on the updating problem. If we stored the test titles in the |
I wouldn't consider this a bug, it has no practical effect and doesn't contradict any documentation.
|
Awesome work, thank you @ninevra and happy new year 🎆 |
Causes
--update-snapshots
to remove snapshot and report files if a test file stopped using snapshots.The removal of snapshot and report files does not trigger
--watch
mode to rerun tests.Snapshot & report files will not be removed if
test.skip()
,test.only()
,t.snapshot.skip()
,--match
, or line number selection were used.--match
and line number selection throw when used with--update-snapshots
(as they did before), and the other cases printCould not update snapshots for ...
.Causes
--update-snapshots
not to update snapshots ift.snapshot.skip()
was used. This is in line with the already documented behavior. Previously, thet.snapshot.skip()
assertion would fail, but no special report would be issued (likely allowing the failure message to be suppressed by a previous assertion failure) and snapshots would be updated anyway. Not technically a breaking change. Could theoretically break workflows that programmatically run--update-snapshots
and skip assertions.Promotes
[email protected]
, previously a transitive dependency, to a top-level devDependency.Possible future work (issues which came up in this process but are out-of-scope here):
Could not update snapshots for ...
message--update-snapshot
interface and edge cases.failing()
tests? (see Remove snapshot files when a test file stops using snapshots #2623 (comment))--update-snapshots
can currently produce different comparison behavior in different test files in the same run; see Remove snapshot files when a test file stops using snapshots #2623 (comment))Original post from draft pull request
Removes snapshot and report files if a test file stops using snapshots.
The removal of snapshot and report files should not trigger
watch
mode to rerun tests.Will close #1424 when complete.
Temporarily blocked on avajs/eslint-plugin-ava#315.
So, I may have gone a little overboard with this. In particular:
I read the intent here as: snapshot files should not be removed if for some reason this test run is not representative, i.e. the user might not have been intending to stop using snapshots or might be intending to use them again soon.
With that understanding, I identified several more cases in which snapshot files maybe shouldn't be removed:
.skip()
ed (since hooks can contain snapshots)afterEach
hooks)t.snapshot()
assertion)failing()
(since failing tests can throw exceptions) (*).only()
,--match
, or line number selection.(Currently, I've implemented and tested all of these checks, but probably some or all of them should be removed.)
However, this behavior (not updating snapshots on unrepresentative runs) is inconsistent with the existing behavior of
--update-snapshots
.--update-snapshots
currently shares only thetest.skip()
restriction and the last restriction on the above list. In the normal case where--update-snapshots
was passed, some snapshot assertions were called, and some were.skip()
ed,--update-snapshots
will happily delete the snaphots that were.skip()
ed.It seems odd that
--update-snapshots
, when given 9t.snapshot.skip()
and 1t.snapshot()
, would delete 9 snapshots, but when given 10t.snapshot.skip()
would delete none.--update-snapshot
s behavior be changed to incorporate some or all of the above checks?(*): the
t.failing()
check is probably too coarse. Tests might be marked failing for a long time, so they probably shouldn't interfere with updating other tests' snapshots. Not sure how to refine this yet. If we don't care about snapshots in hooks, then the failing assertions check can be dropped and thet.failing()
check can be refined to only block updating if an exception is thrown in the test.IssueHunt Summary
Referenced issues
This pull request has been submitted to: