xUnit Test Patterns
Test Goals
- Defect Localization: tells you what specifically went wrong
- Repeatable Test: can be run many times in a row
- Tests as Documentation: should be readable
Test Smells
- Conditional Test Logic: some test code may or may not be executed
- Production Logic in Test: duplicates the production code, not verifying anything
- Related: Flexible Test
- Erratic Test: sometimes pass and sometimes fail
- A cause: Interacting Test: tests depend on other tests in some way. Goal: test isolation.
- A cause: Nondeterministic Test
- Fragile Test: fails when seemingly-unrelated code is changed
- Hard-to-Test Code: (self-explanatory)
- High Test Maintenance Cost: effort keeping tests passing is more than the benefit
- Obscure Test: difficult to understand at a glance
- Eager Test: verifies too much in one test
- Incorrect amount of detail
- Irrelevant Information: data not necessary to understand the test set up inside the test
- Mystery Guest: data necessary to understand the test set up outside the test
- Indirect Testing: checked via interacting with a separate object
Patterns
- Calculated Value: Meszaros considers it a pattern, I generally consider it a smell.
- Fixture
- Fresh Fixture: setting up a new fixture for each test.
- General Fixture: larger than needed to verify the functionality. (Could consider this a smell.)
- Minimal Fixture: smallest and simplest fixture possibile to verify the functionality.
- Shared Fixture: reusing the same fixture for multiple tests. (Could consider this a smell.)
- Hard-Coded Test Data: solves production logic. Meszaros says it's a smell, but then says "better to enumerate the sets of precalculated values" to solve production logic.
- Setup
- In-Line Setup: done in the test function itself
- Delegated Setup: explicitly call functions to set up the data
- Parameterized Creation Method: (factories)
- Implicit Setup:
setUp()/beforeEach()
- Single-Condition Tests: verify one condition per test
Slapdash