Unit tests are tests which verify the design of a tiny piece of code. Test-driven development is a design tool, not a test tool, but has the happy side effect of serving as automated regression tests going forward. Component tests verify the code architecture, making sure the units communicate properly. Both types of tests are used by and for the programmers.
Requirements are really tested at what some people call the acceptance test level, also known as story tests or customer-facing tests. We also write these tests in advance of writing the code, using examples of desired and undesired behavior provided by the business experts. Ideally, these can be specified as executable, automatable tests, which may test the business logic, the user interface functionality, the database access. These tests will exercise more paths through the code than the unit and component tests.
We also need end-to-end tests which test through all the layers of the application. These may be done manually or it may be possible to automated some or all of them. Most importantly, we need to do exploratory testing. Only a person with critical thinking skills and a desire to learn more about the system can do adequate exploratory testing. Unfortunately, many teams never have time for exploratory testing, because they spend all their time doing manual regression tests.
This was first published in September 2010