Skip to content
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

Splitting Snapshot Files #2676

Closed
ticky opened this issue Jan 23, 2017 · 13 comments
Closed

Splitting Snapshot Files #2676

ticky opened this issue Jan 23, 2017 · 13 comments

Comments

@ticky
Copy link
Contributor

ticky commented Jan 23, 2017

Do you want to request a feature or report a bug?
Request a feature

What is the current behavior?
Currently, when using snapshots, a snapshot file is created per test file. In cases where test cases are generated, the snapshot files can become thousands of lines, which makes them unwieldy.

What is the expected behavior?
It would be useful to be able to break up these large, complex test files. I’d propose either some sort of hook in the Jest API;

/// index.spec.js
import myCoolThing from './index';

const TEST_CONDITIONS = [
  {meow: true, nya: false},
  {meow: true, nya: true},
  {meow: false, nya: false}
];

describe('my cool thing', () => {
  TEST_CONDITIONS.forEach(({ meow, nya } => {
    it(`does some things when meow is ${meow} and nya is ${nya}`, () => {
      expect(myCoolThing(meow, nya)).toMatchSnapshot();
    });
    jest.splitSnapshotFile(); // here’s the new magic
  });
});

Should result in __snapshots__ containing;

index.spec.js-1.snap
index.spec.js-2.snap
index.spec.js-3.snap

Or the ability to specify the maximum size (actual interpretation of “size” open to opinions - bytes? lines? results?) of any given snapshot file.

For cases where Jest is used for integration testing or to test several different configurations within something complex, this would allow for nicer output, especially when testing large chunks of React component output!

@orta
Copy link
Member

orta commented Jan 23, 2017

Another option is to make toMatchSnapshot take a configuration object, in our iOS snapshot matchers we support passing in a filename, or (unimportant for this conversation) iOS specific options

@kentaromiura
Copy link
Contributor

What you can do right now, it's changing your test generator to make a single test file per expectation.
Another option could be using beforeAll and afterAll to manually setup the environment like you describe:

beforeAll(joinAllSnapshots)
afterAll(splitAllSnapshots)

where splitAllSnapshots can just require the generated snapshot file and then write each exports down in parts in a folder and then delete the main snapshot file.
joinAllSnapshots can just do a dir list with fs.readdirSync and create a single snap file where Jest will expect it to be.

This way you can keep the .split files on your version controlled system and Jest will just work as intended, I think as long as you don't use .snap as extension for the split file should work ok.

@ticky
Copy link
Contributor Author

ticky commented Jan 23, 2017

a single test file per expectation

This relies on all your tests having names which are valid file paths, or doing some sort of semi-destructive transform on them, and that’s not really the granularity I want, either!

using beforeAll and afterAll to manually setup the environment

This is more viable, but not exactly the nicest way to approach this. It’s bad enough to write complicated filesystem code just to write tests, so writing such a thing to make my test snapshots come out in a nice format seems like bad news! Likewise, having to create/delete files all the time feels like a bad move for SSD longevity 😉.

@cpojer
Copy link
Member

cpojer commented Jan 23, 2017

I'm heavily against this because it will make tracking of snapshot files harder and would require more static analysis. There are two questions you should ask yourself:

  • Do I really need snapshots that are this big?
  • Can I split these huge snapshots up into multiple test files that share common test utilities?

Answering one or both of these questions should lead to smaller snapshot files. Especially the second one is essentially a "user-land implementation" of your feature that comes at no additional complexity for Jest.

Also, SSDs don't suffer the longevity issues any more, so that isn't really a concern here.

@cpojer cpojer closed this as completed Jan 23, 2017
@ticky
Copy link
Contributor Author

ticky commented Jan 23, 2017

Do I really need snapshots that are this big?

It’s less the big and more that I don’t necessarily need to store them repeatedly - there’s no way for me to declare, as it stands, “these combinations of situations should all map to this result,” which is what leads to the large snapshot file sizes.

Can I split these huge snapshots up into multiple test files that share common test utilities?

I mean, technically yes, but in the case of the example, what you end up with is three files which test slight variations on the same thing, and worse, would actually serve to make writing combinations of those cases more difficult.

@cpojer
Copy link
Member

cpojer commented Jan 23, 2017

I feel like the correct answer here would then be to write a diff engine that will make it so that your snapshot will only capture the difference between the items, rather than all the content. @xixixao actually just asked about this at FB last week.

@thymikee
Copy link
Collaborator

I remember @pedrottimark was discussing somewhere about diffSnapshot thing.

@cpojer
Copy link
Member

cpojer commented Jan 24, 2017

I will eventually catch up to @pedrottimark's awesome issues where he discusses these things, mostly with himself (sorry I haven't been able to keep up, please keep posting issues. I see them :D )

@cpojer
Copy link
Member

cpojer commented Jan 24, 2017

See #2197 and #2202.

@usulpro
Copy link

usulpro commented Dec 6, 2019

Having an option to store each snapshot to a separate file would be super useful for cases like NextJs pages snapshots where you can simply require all files from pages/ folder. At this moment I have a snapshot file of ~2Mb and it's even not a half of all pages. It looks like continuing adding snapshots this way isn't scalable. Splitting the single simple test with looping over pages-files into manually or auto-generated list of test files looks overcomplicated as well

@armano2
Copy link
Contributor

armano2 commented Dec 16, 2019

@cpojer we have similar issue at typescript-eslint , biggest one being ~3mb (we have few of those), ability to output them per test (or per option) will be really useful. typescript-eslint/typescript-eslint#1142

Additionally in my alignment test project i'm running exactly same test over ~17k files and for now i decided to not generate snapshots because having it all in single file will be unusable


similar issue was rised by storybook, and their solution was to use cusom implementation:
https://github.com/storybookjs/storybook/pull/1584/files

@milahu
Copy link
Contributor

milahu commented Dec 22, 2020

another use case:
reduce number of escapes / pretty-print snapshots / get human-readable snapshots
in my case, i generate JS source code, which looks ugly when stuffed into a string

solved by jest-specific-snapshot - thx @armano2 : )
edit: not solved. snapshots are still stored as string via saveSnapshotFile

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants