The criteria for a good test are that the test fails for a known reason—not any other reason—and that it’s the only test in the system that fails for that reason. In other words, tests should be unique.
When you have unique tests and you don’t have redundant tests, then you get clean feedback when something fails. Typically one test will break, rather than a whole suite of them, and you won’t have to spend weeks trying to clean up those tests.
This is a primary way teams fail when they adopt TDD. They think: Two tests are good, three tests are great, so ten tests must be fantastic. Let’s just write a whole bunch of tests.
But then you end up with test redundancy in the system. When you go to refactor your code, it means you may have to refactor a lot of tests, which slows you down considerably. It means that when something fails, you’re going to have multiple tests fail for the same reason. That makes your tests noisy—we’ve got to figure out what the real problem is.
Test-first development is a design methodology. It helps developers build high-quality code by forcing them to write testable code and by concretizing requirements.
If you’re going to write a test for something, you need to have some way to verify it in the first place. So write things in manageable chunks—the smaller, the better. Further, write code that’s focused and about one thing. If you have multiple issues in a class, you start to have multiple reasons that the test could fail. As a result, there’s an exponential increase in the number of tests you have to write for the number of issues you have in a class.