Tests are interesting, because you're trying to test code. But to write tests, you have to write code. Who tests the tests? For tests to be worth it you need to be sure that for each line of code you add, the value being added is more than the liability.
Value > Liability
Because belive me, tests are a liability. First, they are code that needs to be maintained just like any other code (and not even tested!). They also naturally hardcode things about your app, which makes it harder to change those things. If you bunker down your app too much with tests, it's impossible to change without huge amounts of work updating all the tests.
This happens especially with integration testing because it usually involves mock data. You want to test your app workflows against mock data, but how do you test if it was successful? One option is to hardcode the values of all the mock data throughout all your tests. After processing all the mock data, value X should be 473.86. Imagine scattering thousands of these values across all your tests.
And then imagine changing the mock data.
It's so easy to mire yourself down with tests. Making changes in your system should not require an equal amount of work updating the tests. There needs to be a balance between testing and adaptability.
Snapshot testing solves the above case. You don't have to embed any values in your test, you just snapshot the relevant parts of the data, and you'll still get failures when the results aren't what they should be. It removes a ton of boilerplate code for checking values and provides great insight into what's happening in your system. And the best part: when your mock data changes, run a simple command to update all of your snapshots.
You should review the changes, of course, especially if your mock data changed in order to cover new test cases. But you'd have to change all the hardcoded values in your tests anyway. Snapshots just automate it.
Yes yes and yes. Also for complex async scenarios where I basically have to assert that X happened before Y - I can create a 'trace string' (like what you'd see in the console), and assert that the trace string matches a snapshot. That really reduces the time to write the test, as I was already putting in console.logs while developing it anyway!