DEV Community

"I need to change this code, but it has no test"

Nicolas Carlo on January 12, 2019

This article was originally written for my personal blog. I am republishing it here for the DEV community. Here's the deal: you need to change t...
Collapse
 
lexlohr profile image
Alex Lohr

I would disagree on the assertion that snapshots had few valid use cases.

First of all, their most valuable effect is to make changes visible. However, you need to review those changes to make use of the snapshot.

Then, in many cases, you'll expect some more complicated object to be returned. While you can write down that object in the test and handle each necessary change manually, you can let snapshots do that for you to the same effect.

Especially for test driven development, having the difference in output easily visible is a good way to verify the incremental changes with less work than you'd otherwise have. Obviously, the snapshot is then but a supplement to an actual test, but it will ease your work nevertheless.

Collapse
 
nicoespeon profile image
Nicolas Carlo

Hi Alex!

I don't see how you could TDD (as "write the test before changing the code") using snapshots. Do you have an example in mind?

Concerning complex objects, snapshots can be really handy indeed. Though, I would first ask myself:

  • Is my test actually testing the complete object? If I only care about some properties, I can use Jest's toMatchObject() for example.
  • Can I change the design so it's not that complex to write the expected object first? It really depends on what kind of object we're dealing with
  • Can I refactor my tests so it's not that difficult to see the expected changes? I might come up with a factory, for example.

But this often happens to me when I didn't write the tests first and I'm working with existing code, which is complex. I also realize that if it's complex for me to use in tests, it might be complex for other consumers of this code to reason about/use.

Although, I do use snapshots in such cases too:

  • either because it's code that didn't have tests in the first place, and I don't have time to write them by hand (which is more or less the scenario I described here)
  • either because we're dealing with UI tests (e.g. testing the rendered React view)

Either way, snapshots are "anti-regression" tests. Which is a valuable tool that I like to have. But when possible (and relevant), I try to think about what I want the code to do and I write an automated test first.

Collapse
 
lexlohr profile image
Alex Lohr

You can actually write the snapshot itself as if it was code. The main advantage over toMatchObject(...) is that you can also use property matches like Any<Date> in there.

Thread Thread
 
nicoespeon profile image
Nicolas Carlo

Oh, I see! Indeed, that's an interesting way to do, thanks for sharing 😃

I wonder though: couldn't you use expect.any(…) to achieve the same, in your test code instead?

Thread Thread
 
lexlohr profile image
Alex Lohr

Not sure. Let me test later, have a bunch of meetings ahead now.

Thread Thread
 
lexlohr profile image
Alex Lohr

It actually seems to work.

Collapse
 
tbeijen profile image
Tibo Beijen • Edited
"To me, good test coverage comes as a side-effect of a good testing strategy (TDD). It's not a target."

"I like it because it expresses the intention better"

Liking these parts. :) Nice write-up!

I'm hearing things about mutation testing being the 'better' quality metric for a test suite (compared to coverage which indeed proves very little).

Not sure (yet) how to do that in CI, but this article gives some inspiration on how to use it while writing tests. Interesting topic.

Collapse
 
nicoespeon profile image
Nicolas Carlo

Thanks for sharing Marc, this could have indeed interesting use-cases.

In the blog post example, I think snapshots are what we want to use though. We don't want to check just the structure, but the actual content of the data.

But I'll keep JSON schema in mind, it could be useful 👍

Collapse
 
jenc profile image
Jen Chan

Thanks for writing this post. I keep hearing about including tests in code but never know where to start.