I propose a straightforward flow for developers who apply effective and systematic testing. First, we implement a feature, using tests to facilitate and guide development. Once we are reasonably happy with the feature or small unit we’ve coded, we dive into effective and systematic testing to ensure that it works as expected (that is, we test to find bugs). Figure 1.4 illustrates the development workflow in more detail; let’s walk through it:
Figure 1.4 The workflow of a developer who applies effective and systematic testing. The arrows indicate the iterative nature of the process; developers may go back and forth between the different techniques as they learn more about the program under development and test.
- Feature development often starts with a developer receiving some sort of requirement. Requirements are often in the form of natural language and may follow a specific format, such as Unified Modeling Language (UML) use cases or agile user stories. After building up some understanding (that is, requirement analysis), the developer starts writing code.
- To guide the development of the feature, the developer performs short test-driven development (TDD) cycles. These cycles give the developer rapid feedback about whether the code they just wrote makes sense. They also support the developer through the many refactorings that occur when a new feature is being implemented.
- Requirements are often large and complex and are rarely implemented by a single class or method. The developer creates several units (classes and methods) with different contracts, and they collaborate and together form the required functionality. Writing classes such that they’re easy to test is challenging, and the developer must design with testability in mind.
- Once the developer is satisfied with the units they’ve created and believes the requirement is complete, they shift to testing. The first step is to exercise each new unit. Domain testing, boundary testing, and structural testing are the go-to techniques.
- Some parts of the system may require the developer to write larger tests (integration or system tests). To devise larger test cases, the developer uses the same three techniques—domain testing, boundary testing, and structural testing—but looking at larger parts of the software system.
- When the developer has engineered test cases using the various techniques, they apply automated, intelligent testing tools to look for tests that humans are not good at spotting. Popular techniques include test case generation, mutation testing, and static analysis. In this book, we cover mutation testing.
- Finally, after this rigorous testing, the developer feels comfortable releasing the feature.
Leave a Reply