CPSC 333 --- Lecture 22 --- Friday, March 8, 1996 Additional "White Box" Tests for Unit Testing Condition Testing: Goal: Thoroughly exercise every condition in the program. Types of Conditions: 1. Simple Conditions (a) Relational Expressions: These have the form "E1 op E2" where E1 and E2 are arithmetic expressions (having numerical values) and "op" can be any of - "is strictly less than" - "is less than or equal to" - "is strictly greater than" - "is greater than or equal to" - "is equal to" - "is not equal to" (b) Boolean Variables --- or calls to Boolean Functions 2. Compound Conditions --- built up from simple(r) conditions using the logical connectives "AND," "OR," and "NOT" (and possibly also "IMPLIES", "EXCLUSIVE OR," etc.) Tests to be Designed: - If the condition is a simple condition: (a) If the condition is a relational expression, "E1 op E2," then design (three) tests such that (i) E1 is strictly less than E2 (ii) E1 is equal to E2 (iii) E1 is strictly greater than E2 (b) If the condition is a Boolean variable (or an evaluation of a Boolean function) then design (two) tests such that (i) The condition has value "true" (ii) The condition has value "false" - If the condition is a compound condition: Suppose it depends on k relational expressions, and l Boolean variables or functions. Then, (try to) design tests such that each of the 3^k x 2^l possible combinations of the values for the relational expressions and Boolean variable-or-functions, given by (a) and (b) above, is covered by at least one test. Example: Consider the "sorting" program used in the Wednesday, March 6 lecture ("lecture_21"). Three test cases were developed for this program (using "path testing"): Test #1: Input: n=1; A[1] = 1 Expected Output: A[1] = 1 Test #2: Input: n=2; A[1] = 1; A[2] = 2 Expected Output: A[1] = 1; A[2] = 2 Test #3: Input: n=2; A[1] = 2; A[2] = 1 Expected Output: A[1] = 1; A[2] = 2 The program contains two conditions: (i) "i <= n" (Outer while loop test) (ii) "(j >= 1) and (A[j] > A[j+1])" (Inner while loop test) We obtain three conditions to be checked from the outer while loop test: (i) i is strictly less than n (ii) i is equal to n (iii) i is strictly greater than n We obtain 3^2 = 9 conditions to be checked from the inner while loop test: (iv) j is strictly less than 1, and A[j] is strictly less than A[j+1] (v) j is strictly less than 1, and A[j] is equal to A[j+1] (vi) j is strictly less than 1, and A[j] is strictly greater than A[j+1] (vii) j is equal to 1, and A[j] is strictly less than A[j+1] (viii) j is equal to 1, and A[j] is equal to A[j+1] (ix) j is equal to 1, and A[j] is strictly greater than A[j+1] (x) j is strictly greater than 1, and A[j] is strictly less than A[j+1] (xi) j is strictly greater than 1, and A[j] is equal to A[j+1] (xii) j is strictly greater than 1, and A[j] is strictly greater than A[j+1] Some, but *not all,* of these conditions are exercised by the three tests we obtained last week. (ii) --- exercised by Tests #2 and #3, during the first execution of the outer while loop (iii) --- exercised by Test #1 and (at the end of the execution, just before the outer while loop terminates) every other test which ends with "normal" termination (iv), (v), (vi) --- Inspection of the code confirms that, if j is less than 1, then "A[j]" is undefined. We *hope* that the condition will be given value "false" if evaluated when j<1 (and that A[j] won't be inspected). Depending the programming language (and possibly the compiler) used, this *might* be the case. We'll treat these three as a single condition --- "j is strictly less than 1." This condition is executed by one of the above three tests --- namely, Test #2 (during the second execution of the inner while loop). (vii) --- exercised by Test #2 (during the first execution of the inner while loop) (ix) --- exercised by Test #3 (during the first execution of the inner while loop). Conditions that are *not* exercised by any of the current tests are: Condition (i) --- only occurs if the input array has size at least three. Condition (viii) --- requires that the first and second array elements initially have the same value, of that they have the same value at some later point in execution (when we're trying to "bubble" a value down into positions one or two of the array) Conditions (x), (xi), (xii) --- Each require input arrays of length at least three, plus additional conditions. We can cover these conditions by introducing four new tests. Test #4: Input: n=2, A[1] = 1, A[2] = 1 Expected Output: A[1] = 1, A[1] = 1 ... this exercises condition (viii) Test #5: Input: n=3, A[1] = 1, A[2] = 2, A[3] = 3 Expected Output: A[1] = 1, A[2] = 2, A[3] = 3 ... this exercises conditions (i) and (x) Test #6: Input: n=3, A[1] = 1, A[2] = 2, A[3] = 2 Expected Output: A[1] = 1, A[2] = 2, A[3] = 2 ... this exercises conditions (i) and (xi) Test #7: Input: n=3, A[1] = 1, A[2] = 3, A[3] = 2 Expected Output: A[1] = 1, A[2] = 2, A[3] = 3 ... this exercises conditions (i) and (xii)