loading...

Yet another reason to prefer unit tests πŸ˜‡

d_ir profile image Daniel Irvine πŸ³οΈβ€πŸŒˆ ・2 min read

Have you ever gotten so frustrated when writing a unit test that you gave up and wrote an end-to-end test instead?

I think this is a common occurrence in the JavaScript world. Codebases become complex very quickly, and then (unsurprisingly) unit tests become complex too.

It seems to me that this is one reason why people prefer end-to-end tests over unit tests: because unit tests can be difficult and frustrating.

But this is precisely why unit tests are useful: unit tests give you design feedback.

If your unit test is hard to write, then that’s a good thing: the test is telling you that your design can be improved.

When you’re faced with a hard-to-write unit test, the solution is not to rewrite your test to be an end-to-end test. The solution is to refactor your production code until the unit test becomes easy to write.

A unit test is like a clamp that holds your system in place while you refactor around it.

If you’re puzzled as to what I’m talking about, then perhaps you would do well to read a book like Kent Beck’s Implementation Patterns or 99 Bottles of OOP by Sandi Metz. (And if you’re a React developer, consider reading my book, Mastering React Test-Driven Development.)

Most developers are well aware of how to make their own code simpler. And yet they don’t do it.

Very often, developers don’t have enough trust in themselves to refactor safely. They fear causing unexpected regressions. They worry that they’ll spend all day refactoring and they won’t make progress on their assigned work.

If that’s you, try giving unit testing another go. Listen to the tests and let them give you the structure you need to make positive change to your codebase.

Posted on Mar 3 by:

d_ir profile

Daniel Irvine πŸ³οΈβ€πŸŒˆ

@d_ir

I’m the author of Mastering React Test-Driven Development, available now from Packt. I run the Queer Code London meetup.

Discussion

markdown guide
 

I came to the conclusion that often integration tests are just fine and give me a better confidence that an application as a whole is working as expected.

For utility libraries that I publish on NPM I unit test everything.

 

I find much more frustration in e2e testing. I'd you write pure functions and stay away from DI, unit testing is relatively easy.

 

True, except when you have to write unit tests for an app where everything is extremely coupled and has 0 tests, which is exactly where I'm at right now :(

 

Agree. This is much more difficult with a spaghetti/legacy project :)

The other dilemma is while the developer may want to refactor something - that time/cost has to be factored in somewhere and often it's a difficult to sell to the client: 'if it ain't broke don't fix it...'

 

I also find it really difficult to unit test things like React components with state, context, etc. The functions these components depend on, sure.

Maybe I just don't know how to write testable React components but to me it seems like more trouble than it's worth, most of the time.

 

Dan! It's so good to see you here, mate :)

Everyone reading this should immediately follow Daniel! He is an incredible coach and amazing at motivating you to write beautiful code.

 
 

You need to be very wise to know when is enough e2e testing, because it can slow down your test suite. In general there should be way more unit test than e2e tests.