DEV Community

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.

Discussion

pic
Editor guide
Collapse
n1ru4l profile image
Laurin Quast

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.

Collapse
g_abud profile image
Gabriel Abud

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.

Collapse
jdforsythe profile image
Jeremy Forsythe

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

Collapse
thecodingalpaca profile image
Carlos Trapet

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 :(

Collapse
jimpriest profile image
Jim Priest

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...'

Collapse
thecodingalpaca profile image
Carlos Trapet

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.

Collapse
d_ir profile image
Daniel Irvine πŸ³οΈβ€πŸŒˆ Author

πŸ€— Thanks! Nice to see you here!

Collapse
victorhazbun profile image
Victor Hazbun

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.