Defining the unit in Unit Tests

Where we consider what a unit is when we talk about unit tests, with some help from Michael Feathers.

The other day I was listening to and episode of Dave Farley’s podcast The Engineering Room where he was talking with Michael Feathers (you can find it on YouTube or on your favorite podcast platform). They covered a lot of ground, and it’s well worth a listen. As are all the episodes.

A bit into the conversation Michael talks about what we name our tests. Many don’t like the term unit test. It’s too vague. So other names have been surfaced, like programmer tests, micro tests, and the list goes on. And then he says:

“And I felt like it might be an interesting thing to flip around and say, well, we could call them unit tests. And then people would say, what’s the unit? And I’d say, well, it’s the thing you can test easy.”

Michael Feathers in From The Engineering Room with Dave Farley: Legacy Code, OOP vs Functional Programming & MORE | Michael Feathers In The Engineering Room Ep. 10, 31 Jan 2024

It struck a cord in me. This is exactly what I’ve tried to tell people when we talk about unit tests. It’s a vague definition because it depends on context. It may be a single function with important and complex logic, or it may be a couple of classes working together. As long as we can easily control the inputs and the outputs to create deterministic and fast tests the size of the unit is not that important. If we have a bunch of classes and our setup becomes cumbersome we should perhaps look at splitting it up into several units.

Working like this also tends to guide us towards more cohesive design. Especially when we work in legacy codebases that are missing tests. As we refactor and add new tests cohesion along these lines falls naturally. The tests help us identify good units.