Book: Software Engineering at Google
Chapter: 12 - Unit Testing
Summary:
Unit tests refer to tests of relatively narrow scope, like a single class or method. Due to it's prevalence compared to functional tests, maintainability of these tests is important for effective work. Maintainable tests, as opposed to brittle ones, are those that engineers write and are unchanging against the system under test; they are ensured that if the tests fail, those indicate real bugs.
To create maintainable tests, some good practices are:
Test via Public APIs: Such tests are more realistic and less brittle because they form explicit contracts. If such a test breaks, it implies that an existing user of the system will also be broken.
Test state, not interactions: Interaction tests check how a system arrived at its result, whereas the engineer should only care what the result is. Interaction details may change from refactoring, yet the result is not, therefore making tests on state to be less brittle.
Make tests complete and concise: Only include information necessary for the test to produce the result, and no other irrelevant or distracting ones.
Test behaviors, not methods: A single method often does a few different things internally. Instead of writing a test for the method, write a test for each behavior of the method, that is an assertion that the system makes when given certain inputs in a certain state.
Behaviors can be expressed as a "given"-"when"-"then" sequence, which is a good framework to structure behavior-driven tests
Don't put logic in tests: In tests, choose straightforward code over clever logic, as logic creates another level of complexity to tests that we might fall into. Consider duplicating data when it makes the test more descriptive and meaningful.
Write clear failure messages: A good failure message clearly distinguishes the expected from the actual state and gives more context about the result.
DAMP, not DRY: While system code are generally DRY (Don't Repeat Yourself), opt for DAMP (Descriptive and Meaningful Phrases) in tests, as to make the tests understandable within its own and not to fully inspect test files to comprehend them.
Book: Software Engineering at Google Chapter: 12 - Unit Testing
Summary:
Unit tests refer to tests of relatively narrow scope, like a single class or method. Due to it's prevalence compared to functional tests, maintainability of these tests is important for effective work. Maintainable tests, as opposed to brittle ones, are those that engineers write and are unchanging against the system under test; they are ensured that if the tests fail, those indicate real bugs.
To create maintainable tests, some good practices are:
Test via Public APIs: Such tests are more realistic and less brittle because they form explicit contracts. If such a test breaks, it implies that an existing user of the system will also be broken.
Test state, not interactions: Interaction tests check how a system arrived at its result, whereas the engineer should only care what the result is. Interaction details may change from refactoring, yet the result is not, therefore making tests on state to be less brittle.
Make tests complete and concise: Only include information necessary for the test to produce the result, and no other irrelevant or distracting ones.
Test behaviors, not methods: A single method often does a few different things internally. Instead of writing a test for the method, write a test for each behavior of the method, that is an assertion that the system makes when given certain inputs in a certain state.
Don't put logic in tests: In tests, choose straightforward code over clever logic, as logic creates another level of complexity to tests that we might fall into. Consider duplicating data when it makes the test more descriptive and meaningful.
Write clear failure messages: A good failure message clearly distinguishes the expected from the actual state and gives more context about the result.
DAMP, not DRY: While system code are generally DRY (Don't Repeat Yourself), opt for DAMP (Descriptive and Meaningful Phrases) in tests, as to make the tests understandable within its own and not to fully inspect test files to comprehend them.