In software design, a pattern is a reusable solution to solve recurring problems. There are a bunch of them, including for example singleton, factory, builder, facade, proxy, decorator, or adapter, to name a few. Anti-patterns are also patterns, but undesirable ones. Concerning to testing, it is worth to know some of these anti-patterns to avoid them in our tests:
- Second class citizens: Test code containing a lot of duplicated code, making it hard to maintain.
- The free ride (also known as Piggyback): Instead of writing a new method to verify another feature/requirement, a new assertion is added to an existing test.
- Happy path: It only verifies expected results without testing for boundaries and exceptions.
- The local hero: A test dependent to some specific local environment. This anti-pattern can be summarized in the phrase It works in my machine.
- The hidden dependency: A test that requires some existing data populated somewhere before the test runs.
- Chain gang: Tests that must be run in a certain order, for example, changing the SUT to a state expected by the next one.
- The mockery: A unit test that contains too much test doubles that the SUT is not even tested at all, instead of returning data from test doubles.
- The silent catcher: A test that passes even if an unintended exception actually occurs.
- The inspector: A test that violates encapsulation that any refactor in the SUT requires reflecting those changes in the test.
- Excessive setup: A test that requires a huge setup in order to start the exercise stage.
- Anal probe: A test which has to use unhealthy ways to perform its task, such as reading private fields using reflection.
- The test with no name: Test methods name with no clear indicator about what it is being tested (for example, identifier in a bug tracking tool).
- The slowpoke: A unit test which lasts over few seconds.
- The flickering test: A test which contains race conditions within the proper test, making it to fail from time to time.
- Wait and see: A test that needs to wait a specific amount of time (for example, Thread.sleep()) before it can verify some expected behavior.
- Inappropriately shared fixture: Tests that use a test fixture without even need the setup/teardown.
- The giant: A test class that contains a huge number of tests methods (God Object).
- Wet floor: A test that creates persisted data but it is not clean up at when finished.
- The cuckoo: A unit test which establishes some kind of fixture before the actual test, but then the test discards somehow the fixture.
- The secret catcher: A test that is not making any assertion, relying on an exception to be thrown and reporting by the testing framework as a failure.
- The environmental vandal: A test which requires the use of given environment variables (for instance, a free port number to allows simultaneous executions).
- Doppelganger: Copying parts of the code under test into a new class to make visible for the test.
- The mother hen: A fixture which does more than the test needs.
- The test it all: Tests that should not break the Single Responsibility Principle.
- Line hitter: A test without any kind of real verification of the SUT.
- The conjoined twins: Tests that are called unit tests but are really integration tests since there is no isolation between the SUT and the DOC(s).
- The liar: A test that does not test what was supposed to test.