According to Clean Code, the three things that make a clean unit test are readability, readability, and readability.
Readability in tests is probably even more important than in production code. So what makes a test readable? The same standards that make other code readable: clarity, simplicity, and density of expression.
Clean tests will contain a lot of your domain language. That means it will not focus on the technical terms of your testing framework, but rather on the business case the code is implementing.
Clean tests should follow this acronym.
Fast means fast. Tests should run fast because you want to run them as frequently as possible. If your tests are slow, you will not run them often enough and the feedback loop will be longer. Lately, I have been working on a codebase that has around 5000 tests and performs around 8300 assertions in less than 3 seconds. I think that’s a good example of fast tests.
Tests should not depend on each other. It should be clear why a test fails and where you should go to fix the problem. If tests depend on each other, one failing test can cause a lot of depending tests to fail which makes diagnosis more difficult.
You should be able to run your tests in all environment. In your production environment, in your QA environment, and on your local machine. They should not depend on a network connection. If your tests are not repeatable, you will have an excuse for when they fail. Plus you will not be able to run them when the environment is not available.
A self-validating test is a test with a boolean output. It either fails or passes. You should know it directly. You should not have to go through a log file to see which tests failed.
Tests should be written just before the production code. If you write your tests after the production code, the change that you will write code that’s hard to test is much bigger. Writing your tests before the production code always results in code that’s easy to test. And code that’s easy to test is also often clean, clear and simple.