Software Methods and Tools

Kenneth M. Anderson <kena@cs.colorado.edu>

Lecture 20: Structural Testing

Today's Lecture

Structural Testing

Control Flow Graphs (CFGs)

Control Flow Example

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;
Cfg

Types of Code Coverage

White-Box Testing Criteria

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30
Output: 50

Cfg

Statement Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30
Output: 50

Note: We just don't care about the non-executable
statements in the code above. Lines 1, 2, 3, 8, 11,
13, and 15 are simply not significant with respect
to the control flow graph.

Cfg

Statement Coverage: Test Case 2

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=30

Cfg

Statement Coverage: Achieved!

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Test Case 1: X=20, Y=10
Test Case 2: X=20, Y=20

Cfg

White-Box Testing Criteria

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=10

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30
Output: 50

Cfg

Edge Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=10, Y=30
Output: 50

Note: We still cover statements like we did before,
but now the focus is on the edges that we hit.

Cfg

Edge Coverage: Test Case 2

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=15, Y=30

Cfg

Edge Coverage: Achieved!

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Test Case 1: X=20, Y=10
Test Case 2: X=15, Y=30

Note: We missed one edge but since it has to do
with a short circuit operator, edge coverage doesn't care.

Cfg

White-Box Testing Criteria

Condition Coverage: Test Case 1

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=20, Y=10

Cfg

Condition Coverage: Test Case 2

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=5, Y=30

Cfg

Condition Coverage: Test Case 3

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Input: X=21, Y=10

Cfg

Condition Coverage: Achieved!

 1  function P return INTEGER
 2  begin
 3      X, Y: INTEGER;
 4      READ(X); READ(Y);
 5      while (X > 10) loop
 6          X := X - 10;
 7          exit when X = 10;
 8      end loop;
 9      if (Y < 20 and then X mod 2 = 0) then
10          Y := Y + 20;
11      else
12          Y := Y - 20;
13      end if;
14      return 2 * X + Y;
15  end P;

Test Case 1: X=20, Y=10
Test Case 2: X=05, Y=30
Test Case 3: X=21, Y=10

Cfg

Relational Coverage

Relational Coverage, continued

Path Coverage

Path Coverage Example

Coming Up Next