Published on

White-Box Testing Techniques

5 min read | 948 words
Authors

Intro

White-box testing focuses on the internal structure, design, and code implementation (e.g., unit or component tests) using tools such as Jest for JavaScript, JUnit for Java, and Pytest for Python. Programmers typically write white-box test cases. Test Engineer (TE) team members do not necessarily need to be fluent in writing white-box test cases, but it is beneficial to understand the basics.

White-box Testing Techniques

Statement Coverage

Statement coverage focuses on the number of statements (i.e., lines of code) covered by tests. Statement coverage answers the question, "Has each statement in the code been executed"? For example, take the following code snippet:

let age = 21
if (age >= 21) {
  console.log('What would you like to drink?')
} else {
  console.log('You are not old enough to drink')
}

In the previous code, the message "What would you like to drink?" or "You are not old enough to drink" is printed on the screen based on the value of age. There are six statements. The following formula measures statement coverage: "the number of statements tested / the total number of statements x 100". We can use the previous formula to write two test cases to achieve 100% statement coverage in the last code snippet. For the first test case, we can set the variable age equal to 21. The first test case would execute lines 1, 2, 3, and 6, resulting in 66% statement coverage. For the second test case, we can set the value of the variable age to 20. The second test case would execute lines 1, 2, 4, and 5, resulting in 66% statement coverage. The combination of the first and second test cases would achieve 100% total statement coverage.

Decision Coverage

Decision coverage (also known as branch coverage) is the most widely used white-box testing technique and focuses on the number of possible decision outcomes covered by tests. When you think of decision coverage, think of if/else statements, for and while loops, or switches. The following formula measures decision coverage: "the number of decision outcomes tested/the total number of decisions x 100". There are two decision outcomes if we revisit the code snippet from the previous section related to age. The first outcome occurs when age is greater than or equal to 21 and prints "What would you like to drink?" to the screen. The second outcome occurs when age is less than 21 and prints "You are not old enough to drink" to the screen. We can write two test cases to achieve 100% decision coverage for the previous code snippet. For the first test case, we can set the variable age equal to 21. The first test case would execute the first decision outcome resulting in 50% decision coverage. For the second test case, we can set the value of the variable age to 20. The second test case would execute the second decision outcome resulting in 50% decision coverage. The combination of the first and second test cases would achieve 100% total decision coverage. Note that gaining 100% decision coverage equals 100% statement coverage because all statements are covered if a decision outcome is covered.

Condition Coverage

Condition coverage focuses on the number of conditions tested within the decision outcomes in code for either a true or false result. For example, take the following code snippet:

let age = 25
let hasLicense = true
if (age >= 18 && hasLicense) {
  console.log('You are on your way!')
} else {
  console.log('You should not be driving!')
}

In the previous code, the message "You are on your way!" or "You should not be driving!" is printed on the screen based on the age values and hasLicense conditions. We can write two test cases to achieve 100% condition coverage for the previous code snippet. For the first test case, we can set the value of age to 25 and hasLicense to true. The first test case would achieve 50% condition coverage because we have tested the true outcome for both conditions. For the second test case, we can set the value of the variable age to 17 and hasLicense to false. Again, the second test case would achieve 50% condition coverage because we have tested the false outcome for both conditions. The combination of the first and second test cases would achieve 100% total condition coverage.

Summary

In summary, we have covered three white-box testing techniques. TE team members can add their testing expertise to white-box testing in many ways, such as:

  • Collaborating with programmers to design test cases best suited for unit-level, white-box testing
  • Asking questions about the behavior of code during code reviews (e.g., merge requests)
  • Suggesting edge case test scenarios not covered by current test cases
  • Using code coverage tools included with most unit testing frameworks to automate auditing statement, decision, and condition coverage against test objectives.
  • Writing white-box test cases when necessary to help maintain team velocity.