Unit tests test units (that is method or function) in isolation, in a dedicated, controlled environment. Each unit test creates in own environment by instantiating only the classes needed to execute one test, putting them in a known state, then it invokes the method to be tested and verify the outcome. This verification is done by assertions on the behavior of the method (as opposed to its implementation).
Performing the verification on the behavior and not on the implementation is important as this allows modifying the implementation without breaking the unit tests, and therefore using the unit tests as a safety net for the modification.
All language have [at least] one unit test framework whose role is to execute the unit tests. There are two ways to write unit tests: test-first or test-last.
Test-first is also called Test-Driven Development. Basically it takes three steps:
- write a failing test
- write just enought code to make it pass
- refactor the code to clean it up (remove duplication ...)
Proponents of TDD claim that this leads to testable code, while it could be hard to write unit tests after the fact, especially when methods do several things. It is recommended to follow the Single Responsibility Principle.
Regarding the pipe structure and communications protocol example, some guidelines say that
a test is not a unit test if:
- It talks to the database
- It communicates across the network
- It touches the file system
- ...
When a thread reads the pipe and finds
it empty it blocks until a writer
writes into the pipe. Should I use
unit tests to test that class?
I would test the class, but not the blocking read method, as I presume it is build from a blocking call to the read()
function of the Operating System.