Author: Haroon Khalil
-
Structural testing in a nutshell
Based on what we just did, let me define a simple approach that any developer can follow (see figure 3.4): Figure 3.4 Applying structural testing in a nutshell. Arrows indicate the iterative nature of the process. The diamond represents the moment where the developer decides whether to write the test case. The most important thing…
-
Code coverage, the right way
Consider the following requirement for a small program that counts the number of words in a string that end with either “r” or “s” (inspired by a CodingBat problem. Given a sentence, the program should count the number of words that end with either “s” or “r”. A word ends when a non-letter appears. The…
-
Introduction
We discussed using software requirements as the main element to guide the testing. Once specification-based testing is done, the next step is to augment the test suite with the help of the source code. There are several reasons to do so. First, you may have forgotten a partition or two when analyzing the requirements, and you…
-
The role of experience and creativity
If two testers performed the specification-based testing technique I described earlier in the same program, would they develop the same set of tests? Ideally, but possibly not. In the substringsBetween() example, I would expect most developers to come up with similar test cases. But it is not uncommon for developers to approach a problem from completely different…
-
How does this work with classes and state?
The two methods we tested have no state, so all we had to do was think of inputs and outputs. In object-oriented systems, classes have state. Imagine a ShoppingCart class and a behavior totalPrice() that requires some CartItems to be inserted before the method can do its job. How do we apply specification-based testing in this case? See the following listing.…
-
Requirements can be of any granularity
The seven-step approach I propose works for requirements of any granularity. Here, we applied it in a specification that could be implemented by a single method. However, nothing prevents you from using it with larger requirements that involve many classes. Traditionally, specification-based testing techniques focus on black-box testing: that is, testing an entire program or…
-
Go for parameterized tests when tests have the same skeleton
A little duplication is never a problem, but a lot of duplication is. We created 21 different tests for the substringsBetween program. The test code was lean because we grouped some of the test cases into single test methods. Imagine writing 21 almost-identical test cases. If each method took 5 lines of code, we would have a…
-
Test for nulls and exceptional cases, but only when it makes sense
Testing nulls and exceptional cases is always important because developers often forget to handle such cases in their code. But remember that you do not want to write tests that never catch a bug. Before writing such tests, you should understand the overall picture of the software system (and its architecture). The architecture may ensure…
-
Pick reasonable values for inputs you do not care about
Sometimes, your goal is to exercise a specific part of the functionality, and that part does not use one of the input values. You can pass any value to that “useless” input variable. In such scenarios, my recommendation is to pass realistic values for these inputs.
-
When in doubt, go for the simplest input
Picking concrete input for test cases is tricky. You want to choose a value that is realistic but, at the same time, simple enough to facilitate debugging if the test fails. I recommend that you avoid choosing complex inputs unless you have a good reason to use them. Do not pick a large integer value…