...
First, come up with an initial list of end to end, component /service and/or unit tests that will be needed to show that the user story, requirement or improvement works as expected or issue has been fixed.
...
Tests should have names that clearly indicate the behavior being tested. For instance, catalogReturnsMetacardIdWhenIngestSucceeds or errorIsReturnedWhenInvalidUserNameIsProvidedexceptionThrownWhenInvalidUserNameProvided.
Positive and Negative Testing
...
Warning |
---|
Some error scenarios are extremely difficult to test using end-to-end or component /service tests, which makes testing all exception scenarios at the unit test level even more critical. |
...
When writing unit or component /service tests, mock all dependencies that may fail. This allows the tests to guarantee that the unit or component under test behaves as excepted when one of its dependencies fails.
...
Use Proper Clean Up Mechanisms
Always make sure that tests clean up after themselves to ensure that a test failure doesn't impact other tests.
Use the test tool's fixture capabilities (i.e., cleanup/tear-down methods) to perform any required cleanup instead of using finally
blocks.
Smells
Tests Difficult to Name
...
Dependencies Difficult to Mock
Tests Need to be Run in a Specific Order
Anti-Patterns
Sleeps
Sleeps in tests should be avoided as they open the door to timing issues and race conditions, slow tests down and are a major cause of test flakiness.
...
Changing Method Visibility
Test Multiple Behaviors in a Single Test
A test should test one and only one behavior. Having assertions and/or verifications that validate different behaviors makes it difficult to know why a test has failed and doesn't provide a good insight into what is being tested.
Repeated Given, When or Then sections in a BDD test, or difficult to name tests are usually two good indicators that a test is doing too much.