Step 2: Explore what the program does for various inputs

An ad hoc exploration of what the method does may increase your understanding of it. I have noticed this when observing professional software developers writing test cases for methods they have never seen before (Aniche, Treude, and Zaidman, 2021). This step is more relevant when you did not write the code—if you wrote it, this exploration phase may not be needed.

To illustrate this step, suppose you did not write this code (which, in this case, is true). My process would be as follows (see the JUnit code in listing 2.2):

Let’s see the program working on a happy case. I will pass the string “abcd” with the open tag “a” and the close tag “d”. I expect it to return an array with a single element: ["bc"]. I try that (in a unit test), and the program returns what I expect.

Next, let’s see what happens if there are multiple substrings in the main string. I will pass the string “abcdabcdab” with the same open and close tags. I expect it to return an array with two strings: ["bc", "bc"]. The program returns what I expect.

I expect the program to behave the same with open and close tags larger than a single character. I will repeat the second test, doubling the “a”s and the “d”s in all the parameters. I will also change one of the “bc”s to “bf”, so it is easier to check that the method returns two different substrings: ["bc", "bf"]. The program returns what I expect.

Listing 2.2 Exploratory tests for substringsBetween()

@Test
void simpleCase() {                                   ❶
  assertThat(
    StringUtils.substringsBetween("abcd", "a", "d")
  ).isEqualTo(new String[] { "bc" });
}
 
@Test
void manySubstrings() {                               ❷
  assertThat(
    StringUtils.substringsBetween("abcdabcdab", "a", "d")
  ).isEqualTo(new String[] { "bc", "bc" });
}
 
@Test
void openAndCloseTagsThatAreLongerThan1Char() {       ❸
  assertThat(
    StringUtils.substringsBetween("aabcddaabfddaab", "aa", "dd")
  ).isEqualTo(new String[] { "bc", "bf" });
}

❶ We write these test cases based on our feelings. What do we want to explore next?

❷ I don’t care if they are good tests, as long as they teach me something about the code.

❸ I wrote all the test code in a single line, although you cannot see that in the printed. Feel free to write it any way you prefer.

I stop this exploration phase when I have a clear mental model of how the program should work. Note that I do not expect you to perform the same exploration I did—it is personal and guided by my hypothesis about the program. Also note that I did not explore any corner cases; that comes later. At this moment, I am only interested in better understanding the program.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *