Index of /~billard/se/cs4320/ex4

      Name                    Last modified       Size  Description

[DIR] Parent Directory 20-Apr-2008 08:49 - [TXT] avg 19-May-2009 09:03 23k [   ] avg.bat 19-May-2009 09:03 1k [TXT] avg.c 19-May-2009 09:03 5k [   ] comp.bat 19-May-2009 09:03 1k [TXT] max 19-May-2009 09:03 23k [TXT] max.c 19-May-2009 09:03 1k [TXT] maxab 19-May-2009 09:03 23k [   ] maxab.bat 19-May-2009 09:03 1k [TXT] maxab.c 19-May-2009 09:03 4k [TXT] maxabc 19-May-2009 09:03 23k [   ] maxabc.bat 19-May-2009 09:03 1k [TXT] maxabc.c 19-May-2009 09:03 2k [TXT] minmax 19-May-2009 09:03 23k [TXT] minmax.c 19-May-2009 09:03 1k [TXT] passfail 19-May-2009 09:03 23k [   ] passfail.bat 19-May-2009 09:03 1k [TXT] passfail.c 19-May-2009 09:03 3k [   ] print.bat 19-May-2009 09:03 1k [   ] printdoc.bat 19-May-2009 09:03 1k [TXT] while1 19-May-2009 09:03 7k [TXT] while1.c 19-May-2009 09:03 1k


CS 4320 Software Testing and QA: Ex4 WHITE BOX TEST
===================================================

Platform: UNIX or PC

Given: source code

Goal: perform white box testing using cyclometric complexity

White Box Test: given source code, design test cases that exercise various parts of the code.

The idea is that the more paths that are "covered" by the test cases, the more confident
we are in the software - as long as the test cases yield correct answers. But how many
test cases should we make? A million? Two million? The CYCLOMETRIC COMPLEXITY tells us
exactly how many cases we need.

In Ex3, you first learned about Cyclometric Complexity:

  Each predicate in an IF or WHILE condition creates a unique path.
  The number of independent paths is the Cyclometric Complexity and is equal to:

    Predicates + 1 = Edges - Nodes + 1 = Regions - 1

  where Edges, Nodes, Regions are determined by drawing a FLOWGRAPH of the code.

  Path Coverage for white box strategy tests each independent path based on the 
  cyclometric complexity.

  The example from Ex3:

  CODE:

  if (a)
    if (b)
      x;
    else
      y;
  else
    y;
  z;

  FLOWGRAPH:
                   ..............
                   .            .
              F    .    T       .
              +----a----+       .
         R4   | R1      |  R3   .
              v      F  v       .
              y<--------b       .
              | R2      | T     .
              |         v       .
              |         x       .
              |         |       .
              +--->z<---+       .
                   .            .
                   ..............


  CYCLOMETRIC COMPLEXITY:

  CC = P + 1 = E - N + 1 = R - 1 

  CC = 2 + 1 = 6 - 4 + 1 = 4 - 1 = 3

  TEST CASES:

   a     b
  ------------
  True  True
  True  False
  False *

  In summary, the code yields a flow graph with a particular complexity.
  This complexity tells us how many test cases we expect to exactly
  "cover" all of the code. That is what you will do in this exercise.

Metrics:

  The cyclometric complexity - which counts the number of predicates - is
  an example of a "metric" to evaluate the complexity of source code. As the
  cyclometric complexity increases, so do the number of faults. It is suggested
  that a cyclometric complexity greater than 10 for a function should be avoided.
  Also, the number of faults increases with the metric Lines of Code (LOC or KLOC).

In the following examples, the key points will be:

CODE: The starting point will be given C functions which are designed to compute something
  specific.

FLOWGRAPHS: Using the source code, draw the corresponding flowgraph, where the main 
  purpose is to split at branch points (predicates).

CYCLOMETRIC COMPLEXITY: Compute CC = P + 1 = E - N + 1 = R - 1 

PATH COVERAGE: The CC will be the exact number of test cases needed to provide 100%
  path coverage.

INDEPENDENT PATHS: Determine each of the paths through the code, and there should be
  the same number as CC. No more, no less. What does "independent" mean? Remember 
  Math 2101 Linear Algebra? You formed simultaneous equations which were added or
  subtracted with each other. Our independent paths will NOT be the addition or
  subtraction of another path. More on this later.

BASIS CYCLES: Before we get to loops, basis cycles will look like paths with this
  exception: paths start at the top of the function and work their way to the bottom.
  A basis cycle does the same thing but returns to the top (just like the artificial
  edge). After we introduce loops, basis cycles will not look like paths at all,
  they will just be the loop itself. This is all a mathematical concept that we
  won't explore any further - but you will be responsible for computing the cycles.
  The key point will be that the number of BASIS CYCLES will be the same as the 
  CYCLOMETRIC COMPLEXITY, which is the same as the number of INDEPENDENT PATHS.     
 
INSTRUMENTATION: You probably call this "debug". You'll put debug code in the given
  C function which highlights which "direction" the logic is flowing. That is, it will
  print the PATH the logic is following. This will help you see if your testing is
  working.

TEST CASES: Now that you know the CC number of PATHS, and have INSTRUMENTATION code to 
  print the paths, design the actual test cases which force the function along a particular 
  path. Each test case specifies the input to the function, and the expected return value.
  Although CC determines the exact number of needed tests cases for 100% path coverage, there 
  may be infeasible paths. That is, the flowgraph has a mathematical path but that path 
  may be contradictory in terms of actual data in the code. For example, a TRUE on an IF 
  statement may make it infeasible for a nested IF statement to ever go the FALSE branch. 

AUTOMATED TEST: Given the TEST CASES cases on paper, you will create Unix batch scripts to
  execute the function CC number of times, and feed the function a new test case each time.
  The INSTRUMENTATION will show the logic following the INDEPENDENT PATHS.

You may want to look at the examples provided on the directory now, but here is a summary
of paths and cycles that you can refer to:

What are the strategies for creating Independent Paths and their significance?

  The flowgraphs - from Ex3 - present the logic of the code. Graph theory
  tells us that the cyclometric complexity (predicates + 1) will determine
  the number of independent paths through the code. "Independent" means
  one path is not some combination of addition/subtraction of other paths.
  Although testing cannot prove the absence of bugs, we feel more confident
  about the software if we can test all possible flows through the code.
  And know the number of such paths (CC) helps us to construct the 
  appropriate number of test cases.
  
  Now that we know the number of such paths, we can create a path by
  starting at the top of the flowgraph, flow towards the bottom, but be
  sure to touch at least one new edge. Be patient, not greedy. Try to avoid
  consuming lots of edges in one path. There will always be a way to list
  CC number of paths and to touch at least edge in each one. If you come
  up with CC number of paths, and each one touches at least one new path,
  you know you have the correct solution.
  
What are the strategies for creating a Basis Set of Cycles? 

  There will always be CC number of Basis Cycles, just like Independent
  Paths. And "Basis" has the same meaning as "Independent": not some
  combination of addition/subtraction of other cycles.
  
  Without loops, the cycles look exactly like the paths but they complete
  a "cycle" by returning to the starting node, using the artificial
  edge. With loops, some cycles don't look anything like a path. By
  definition, a cycle must start at a node, and return to the node, but
  cannot visit any other node more than once. So in the case of a loop,
  a cycle will start/stop at the node representing the while condition.
  Other cycles will start at the top but "bounce" off this loop with a 
  false condition. NO CYCLE will ever start at the top and go around the
  loop too. For example, consider:
  
    a;
    while (b) 
     x;
    y;
  
    Two cycles: 
      a,b,y,a (bounce off loop, and use artificial edge)
      b,x,b   (just the loop, touch a new edge)
      
    But this is NOT a cycle:
      a,b,x,b,y,a
      
    Why? Because "b" appears twice and it isn't the start/stop node.
    
    Just like "Independent" paths, if you touch a new edge, you can be sure
    that it's a "Basis" cycle.
    
    Note that the paths would have been:
    
    a,b,y     (don't be greedy)
    a,b,x,b,y (touch a new edge)
    
What is the motivation for Basis Cycles?

  For this course, the only motivation is to test your logic skills as a
  computer science major. Note that CS 2150 Discrete Math is a prerequisite
  and covers Graph Theory. It probably covered the concept of a cycle but
  certainly not "basis" cycles.
 

REMINDERS: 

1. If you touch a new edge then it is INDEPENDENT. 

2. Let's say (as in Ex3.3 #9) Path4 = Path1 + Path2 - Path3.

   But that means that: Path3 = Path1 + Path2 - Path4 (etc.)

   So you can pick ANY 3 out of the 4. Although there are 4 PATHS,
   only 3 (but any 3) can be considered INDEPENDENT.

   It is recommended to list the 3 in such an order that a new edge 
   is touched - just a guarantee.

EXAMPLES:

The first example is simple but illustrates all of the above so be sure
to study it in detail.

a. % more maxab.c
   % more maxab.bat
   % maxab.bat

b. % more passfail.c
   % more passfail.bat
   % passfail.bat
  
c. % more maxabc.c
   % more maxabc.bat 
   % maxabc.bat

d. % more avg.c
   % more avg.bat
   % avg.bat

Perform Path Coverage White Box Test:

e. % more minmax.c

   in the source minmax.c:

     0. label the `lines' of code with L(1), L(2), etc.
     1. FLOWGRAPH (or use a word processor)
     2. CYCLOMETRIC COMPLEXITY
     3. BASIS SET OF CYCLES
     4. LINEARLY INDEPENDENT PATHS   5. FEASABLE (YES/NO)   6. TEST CASES   7. RESULT

     TRY TO GET AS MANY FEASABLE INDEPENDENT PATHS AS POSSIBLE.

   % gcc -o minmax minmax.c

   create minmax.bat which includes all of your test cases. 

   minmax.bat should also indicate expected results like the other .bat files.

   % minmax.bat >minmax.out         // instructor needs to see these too

f. % more max.c

   repeat the above.

   % gcc -o max max.c
   % max.bat >max.out

g. % more while1.c
   
   repeat the above.

   % gcc -o while1 while1.c
   % while1.bat >while1.out

g. project notebook (see print.bat):

   README
   maxab.c
   maxabc.c
   avg.c
   passfail.c 
   minmax.c
   minmax.bat
   minmax.out
   max.c
   max.bat
   max.out   
   while1.c
   while1.bat
   while1.out