Enhancement: snapshot testing for lint rule failures #6499
Replies: 5 comments 8 replies
-
ESLint may support snapshot test in future eslint/eslint#14936 FYI: I build snapshot tester for https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/test/utils/snapshot-rule-tester.mjs |
Beta Was this translation helpful? Give feedback.
-
We have to build something test-framework agnostic (the entire In the past I've leveraged Considering these snapshots are 110% meant to be human-readable, I think we need to go in a different direction and do a custom snapshot format so that we can have syntax highlighting and a nicer experience. I kind of like how AVA does things - a markdown file with the snapshot contents inside code fences. However to avoid parsing markdown ava also dumps out a separate binary blob which is the test metadata - so it compares against the blob and writes the markdown separately for humans. Do we think that two files being written is okay to trade-off for increased human readability? Ava examples - #6499 (comment) |
Beta Was this translation helpful? Give feedback.
-
The other consideration is how many snapshots to create for each test. There's ofc two options - one snapshot per test case, or one snapshot for the entire test file. I can see pros and cons to both - increased readability for the former due to less scrolling / shorter file traded off against having many more files on disk. I'm kind of leaning towards having just one file right now (same as ava and jest do by default) - but I'm open to doing the other way (it's how I've done all of our other snapshot implementations). What do we think? |
Beta Was this translation helpful? Give feedback.
-
In angular-eslint I have managed to solve some of these problems in a different way, and there are additional wins in terms of docs. I think it could be expanded even further with some more custom tooling around the rule tester. Each rule has a
Importantly for the The additional really powerful thing this facilitates is that I generated my docs from the unit tests. So every single covered case is automatically documented and guaranteed to be up to date and verified so long as the unit tests are green: You can still use |
Beta Was this translation helpful? Give feedback.
-
I have a POC ready which creates one markdown snapshot and one binary snapshot for each test file: It looks pretty nice and is pretty easy to understand, I think. As I said here I'd like to make this a progressive enhancement - but maybe it'd be better to just create a brand new way of doing tests? |
Beta Was this translation helpful? Give feedback.
-
Resurrecting #56
At Canva they use a (home grown) package
eslint-snapshot-test
to snapshot the lint rule errors.I found it's a really great way to work because it allows you to visualise the error ranges with the code instead of abstractly referencing the line/cols.
However the ergonomics of the package are off, IMO, because (a) it uses its own custom class to do testing which doesn't have any of the features of ESLint's
RuleTester
and (b) it prefers you organise rule tests as if they were bog standard tests (i.e. within describe/it) which sucks because there's so much boilerplate to reuse.I propose we do two things:
(1) fork the base ESLint rule tester properly. Right now we are subclassing it so that we can add our customisations and it makes the code pretty complicated and convoluted. As I established in #6456 - I think we're getting to the scale with a lot of things where it's just plain better for us to fork instead of extending.
(2) add a new option to the
RuleTester
constructor likesnapshot?: boolean = false
which will automatically compute a snapshot for each invalid test.For example
Would create a snapshot file like:
Which is much, much more readable than the current alternative test:
Pros:
Cons:
description
attribute to help with identification and that each description is unique.This system could also be extended to snapshot fixers.
For example you could envision a separate snapshot emitted for each fixer which is just the raw source output. We could do something similar to what we do with our AST snapshots and emit line-by-line diff of the code and output to make it clearer what the changes were.
In this case we'd emit 3..n snapshots per invalid case - one showing the error report location, (or clearly stating there was no fix performed), one showing the fix diff, and two for each suggestion fixer.
Problem to solve - sane organisation of snapshots.
We might have to think through how this should be structured though because emitting 3 snapshots per invalid test could be REALLY difficult to understand and mentally match up - especially if there are a lot of test cases. TBH just emitting 1 per test could be hard enough given the scale of invalid tests for some rules.
As mentioned before - enforcing the use of
description
could be pretty maintenance-heavy and cumbersome as well. Imagine trying to come up with 100 unique descriptions for tests that are slight syntactic variations. It could easily devolve into users just doing "Test Case 1", "Test Case 2", ... - which isn't really great (even though it would uniquely identify each test case, it would turn into a mess as you reorder the tests).Even though our AST fixture system emits 6 snapshots per fixture (IMO) it is really easy to understand things because each snapshot which is a separate file on disk and is clearly named.
Spitballing possible solutions:
(1) just emit one monolithic snapshot file and trust that users will get used to it and "figure it out"
Pros:
Cons:
(2) create a unique, filename-safe name per test and emit one snapshot file for each test case.
Pros:
Cons:
description
? I.e. push that burden onto the user?jest-specific-snapshot
like we currently do)(3) use the description to create folders on disk and emit individ 8000 ual snapshots.
Pros:
Cons:
(4) break compatibility entirely and instead use a similar structure to our AST fixture system - one file per fixture.
Pros:
Cons:
config.ts
file which exports a config object and provide some utils to easily type the object.(5) do a similar system to
eslint-snapshot-test
in which the user decides how to name tests and how to properly handle the snapshot side of things.For example they could use inline snapshots if they wanted:
Pros:
Cons:
Beta Was this translation helpful? Give feedback.
All reactions