Structural Testing. Testing Tactics. Why Structural? Structural white box. Functional black box. Structural white box. Functional black box

Similar documents
Structural Testing. Testing Tactics. Why Structural? Structural white box. Functional black box. Structural white box. Functional black box

Testing Tactics. Structural Testing. Why Structural? Why Structural? Functional black box. Structural white box. Functional black box

STRUCTURAL TESTING. AKA White Box Testing. Thanks go to Andreas Zeller for allowing incorporation of his materials. F. Tip and M.

STRUCTURAL TESTING. AKA White Box Testing. Thanks go to Andreas Zeller for allowing incorporation of his materials. F. Tip and M.

Structural Testing. (c) 2007 Mauro Pezzè & Michal Young Ch 12, slide 1

Coverage-Guided Fuzzing

Subject Software Testing Structural Testing

MSc Software Testing and Maintenance MSc Prófun og viðhald hugbúnaðar

Introduction to Dynamic Analysis

MSc Software Testing MSc Prófun hugbúnaðar

Program Testing and Analysis: Manual Testing Prof. Dr. Michael Pradel Software Lab, TU Darmstadt

F. Tip and M. Weintraub FUNCTIONAL TESTING

Using the code to measure test adequacy (and derive test cases) Structural Testing

Structural Testing. White Box Testing & Control Flow Analysis

CS 520 Theory and Practice of Software Engineering Fall 2018

MTAT : Software Testing

White-Box Testing Techniques

Testing: Coverage and Structural Coverage

Integration Testing. Conrad Hughes School of Informatics. Slides thanks to Stuart Anderson

6. Test-Adequacy. Assessment Using Control Flow and Data Flow. Andrea Polini

Test design techniques

1 Black Box Test Data Generation Techniques

CS 536 Introduction to Programming Languages and Compilers Charles N. Fischer Lecture 5

c. Typically results in an intractably large set of test cases even for small programs

Integration Testing. Unit Test vs Integration Testing 1. Unit Testing vs Integration Testing 2. Unit testing: isolation, stub/mock objects

Software Testing TEST CASE SELECTION AND ADEQUECY TEST EXECUTION

Dataflow-based Coverage Criteria

Path Testing + Coverage. Chapter 8

Software Testing and Analysis Process, Principles, and Techniques

UNIT-4 Black Box & White Box Testing

MTAT : Software Testing

Software Testing. Lecturer: Sebastian Coope Ashton Building, Room G.18

Test Design Techniques ISTQB (International Software Testing Qualifications Board)

Aerospace Software Engineering

Software Testing for Developer Development Testing. Duvan Luong, Ph.D. Operational Excellence Networks

Black Box Testing (revisited) Csci 565 Spring 2007

UNIT-4 Black Box & White Box Testing

MTAT : Software Testing

Introduction to Software Engineering

Why testing and analysis. Software Testing. A framework for software testing. Outline. Software Qualities. Dependability Properties

Facts About Testing. Cost/benefit. Reveal faults. Bottom-up. Testing takes more than 50% of the total cost of software development

Testing: (A Little) Logic Coverage

Programming Embedded Systems

Verification Overview Testing Theory and Principles Testing in Practice. Verification. Miaoqing Huang University of Arkansas 1 / 80

Design of Digital Circuits ( L) ETH Zürich, Spring 2017

Testing: Coverage and Structural Coverage

Chapter 9. Software Testing

Automated White-Box Testing Beyond Branch Coverage

CHAPTER 5 GENERATING TEST SCENARIOS AND TEST CASES FROM AN EVENT-FLOW MODEL

Testing! The material for this lecture is drawn, in part, from! The Practice of Programming (Kernighan & Pike) Chapter 6!

Specification-based Testing 2

DECISION STRUCTURES: USING IF STATEMENTS IN JAVA

1007 Imperative Programming Part II

Introduction to Software Testing Chapter 2, Sections: 2.1 & 2.2 Overview Graph Coverage Criteria

Software Testing. Testing 1

Examination Questions Time allowed: 1 hour 15 minutes

Feasibility of Testing to Code. Feasibility of Testing to Code. Feasibility of Testing to Code. Feasibility of Testing to Code (contd)

Administrivia. ECE/CS 5780/6780: Embedded System Design. Acknowledgements. What is verification?

Program Verification! Goals of this Lecture! Words from the Wise! Testing!

Functional Programming in Haskell Prof. Madhavan Mukund and S. P. Suresh Chennai Mathematical Institute

CS/ECE 5780/6780: Embedded System Design

Software Testing. Testing: Our Experiences

CIS 890: Safety Critical Systems

MTAT : Software Testing

Overview. State-of-the-Art. Relative cost of error correction. CS 619 Introduction to OO Design and Development. Testing.

Testing! The material for this lecture is drawn, in part, from! The Practice of Programming (Kernighan & Pike) Chapter 6!

Software Testing CS 408

Lecture 14: Chapter 18!

Testing. CMSC 433 Programming Language Technologies and Paradigms Spring A Real Testing Example. Example (Black Box)?

Overview Graph Coverage Criteria

Test Automation. 20 December 2017

OCR GCSE Computing Learning Grids H/W

Part I: Preliminaries 24

Diagonalization. The cardinality of a finite set is easy to grasp: {1,3,4} = 3. But what about infinite sets?

The Gray Code. Script

Software Verification and Validation. Prof. Lionel Briand Ph.D., IEEE Fellow

Testing! Prof. Leon Osterweil! CS 520/620! Spring 2013!

Semantics via Syntax. f (4) = if define f (x) =2 x + 55.

CMPT 473 Software Quality Assurance. Graph Coverage. Nick Sumner

An Empirical Evaluation of Test Adequacy Criteria for Event-Driven Programs

Fachgebiet Softwaretechnik, Heinz Nixdorf Institut, Universität Paderborn. 4. Testing

7. Testing and Debugging Concurrent Programs

LECTURE 18. Control Flow

Coding and Unit Testing! The Coding Phase! Coding vs. Code! Coding! Overall Coding Language Trends!

Lecture Notes on Interfaces

Testing & Continuous Integration. Kenneth M. Anderson University of Colorado, Boulder CSCI 5828 Lecture 20 03/19/2010

Software Quality Engineering: Testing, Quality Assurance, and Quantifiable Improvement

Software Testing. Massimo Felici IF

COMP 3705 Advanced Software Engineering: Software Testing

SE 3S03. Zahra Ali. Week of Feb 22, 2016

false, import, new 1 class Lecture2 { 2 3 "Data types, Variables, and Operators" 4

Written exam TDDD04 Software Testing

Data Flow Testing. CSCE Lecture 10-02/09/2017

An Introduction to Systematic Software Testing. Robert France CSU

Control Structures. Lecture 4 COP 3014 Fall September 18, 2017

People tell me that testing is

An Eclipse Plug-in for Model Checking

Zheng-Liang Lu Java Programming 45 / 79

Lecture Notes on Memory Layout

MTAT : Software Testing

Transcription:

From Pressman, Software Engineering a practitioner s approach, Chapter 14 and Pezze + Young, Software Testing and Analysis, Chapters 12-13 Structural Testing Software Engineering Andreas Zeller Saarland University Testing Tactics n contrast to functional tests (discussed the last time), structural tests are based on the code structure Functional black box Structural white box Tests based on spec Test covers as much specified behavior as possible Tests based on code Test covers as much implemented behavior as possible Why Structural? Structural tests are automated and can be much more fine-grained than functional tests. Functional black box Structural white box f a part of the program is never executed, a defect may loom in that part A part can be a statement, function, transition. condition Attractive because automated

Why Structural? Typically, both techniques are used. Functional black box Structural white box Complements functional tests Run functional tests first, then measure what is missing Can cover low-level details missed in highlevel specification A Challenge Recall this example from last lecture. class Roots { // Solve ax 2 + bx + c = 0 public roots(double a, double b, double c) { // Result: values for x double root_one, root_two; Which values for a, b, c should we test? assuming a, b, c, were 32-bit integers, we d have (2 32 ) 3 10 28 legal inputs with 1.000.000.000.000 tests/s, we would still require 2.5 billion years The Code // Solve ax 2 + bx + c = 0 public roots(double a, double b, double c) { double q = b * b - 4 * a * c; if (q > 0 && a 0) { // code for handling two roots Test this case f we know the code ( white box ) and thus the structure, we can design test cases accordingly if (q == 0) { // code for handling one root // code for handling no roots and this and this!

The Test Cases // Solve ax 2 + bx + c = 0 public roots(double a, double b, double c) { double q = b * b - 4 * a * c; if (q > 0 && a 0) { // code for handling two roots (a, Test b, c) this = (3, case 4, 1) Finding appropriate input values is a challenge in itself which may require external theory but in this case, the external theory is just maths. if (q == 0) { // code for handling one root // code for handling no roots (a, b, and c) = this (0, 0, 1) (a, b, and c) = this! (3, 2, 1) A efect // Solve ax 2 + bx + c = 0 public roots(double a, double b, double c) { double q = b * b - 4 * a * c; if (q > 0 && a 0) { // code for handling two roots if (q == 0) { x = (-b) / (2 * a); code must handle a = 0 // code for handling no roots (a, b, c) = (0, 0, 1) The test case that executes the q = 0 branch reveals a defect the case a = 0 Expressing Structure // Solve ax 2 + bx + c = 0 public roots(double a, double b, double c) { double q = b * b - 4 * a * c; if (q > 0 && a 0) { // code for handling two roots What is relevant in her is the program structure the failure occurs only if a specific condition is true and a specific branch is taken. if (q == 0) { x = (-b) / (2 * a); // code for handling no roots

Control Flow Graph public roots(double a, double b, double c) double q = b * b - 4 * a * c; q > 0 && a!= 0 q == 0 // code for no roots return // code for two roots // code for one root A control flow graph expresses paths of program execution Nodes are basic blocks sequences of statements with one entry and one exit point Edges represent control flow the possibility that the program execution proceeds from the end of one basic block to the beginning of another To express structure, we turn the program into a control flow graph, where statements are represented as nodes, and edges show the possible control flow between statements. public roots(double a, double b, double c) Structural Testing To talk about structure, we turn the program into a control flow graph, where statements are represented as nodes, and edges show the possible control flow between statements. double q = b * b - 4 * a * c; q > 0 && a!= 0 // code for two roots q == 0 // code for one root // code for no roots return The CFG can serve as an adequacy criterion for test cases The more parts are covered (executed), the higher the chance of a test to uncover a defect parts can be: nodes, edges, paths, conditions Control Flow Patterns Every part of the program induces its own patterns in the CFG. while (CON) do for BOY BOY NT while (CON) BOY; if (CON) while (CON) do { BOY while (CON); CON BOY NCR TEN-BOCK ESE-BOCK if (CON) TEN-BOCK; ESE-BOCK; for (NT; CON; NCR) BOY;

cgi_decode /** * @title cgi_decode * @desc * Translate a string from the CG encoding to plain ascii text * + becomes space, %xx becomes byte with hex value xx, * other alphanumeric characters map to themselves * * returns 0 for success, positive for erroneous input * 1 = bad hexadecimal digit */ ere s an ongoing example. The function cgi_decode translates a CGencoded string (i.e., from a Web form) to a plain ASC string, reversing the encoding applied by the common gateway interface (CG) on common Web servers. (from Pezze + Young, Software Testing and Analysis, Chapter 12) { char *eptr = encoded; A while (*eptr) /* loop to end of string ( \0 character) */ { C if (c == + ) { /* + maps to blank */ *dptr = ; E if (c == % ) { /* %xx is hex for char xx */ G if (digit_high == -1 digit_low == -1) /* Bad return code */ /* All other characters map to themselves */ *dptr = *eptr; F B *dptr = \0 ; /* Null terminator for string */ M B A C This is what cgi_decode looks as a CFG. (from Pezze + Young, Software Testing and Analysis, Chapter 12) if (c == '%') { E *dptr = *eptr; F G M

B A C test While the program is executed, one statement (or basic block) after the other is covered i.e., executed at least once but not all of them. ere, the input is test ; checkmarks indicate executed blocks. if (c == '%') { E *dptr = *eptr; F G M A test a+b We d like to test every statement, so we come up with more test cases. B C if (c == '%') { E *dptr = *eptr; F G M A test a+b %3d We d like to test every statement, so we come up with more test cases. B C if (c == '%') { E *dptr = *eptr; F G M

B A C test a+b %3d %g This is an interesting boundary test case, as it may cause non-deterministic behavior. Can you see why? if (c == '%') { E *dptr = *eptr; F G M Test Adequacy ow do we know a test suite is good enough? A test adequacy criterion is a predicate that is true or false for a pair program, test suite Usually expressed in form of a rule e.g., all statements must be covered Statement Testing (from Pezze + Young, Software Testing and Analysis, Chapter 12) Adequacy criterion: each statement (or node in the CFG) must be executed at least once Rationale: a defect in a statement can only be revealed by executing the defect Coverage: # executed statements # statements

100% 75% 50% 63% B A C test The initial coverage is 7/11 blocks = 63%. We could also count the statements instead (here: 14/20 = 70%), but conceptually, this makes no difference. 25% 0% Coverage *dptr = *eptr; F if (c == '%') { G E M 100% A test a+b and the coverage increases with each additionally executed statement 75% 50% 72% B C 25% 0% Coverage *dptr = *eptr; F if (c == '%') { G E M 100% 75% 50% 91% B A C test a+b %3d 25% 0% Coverage *dptr = *eptr; F if (c == '%') { G E M

101% 76% 51% 25% 0% 100% Coverage if (c == '%') { *dptr = *eptr; F B A C G test a+b %3d %g E until we reach 100% block coverage (which is 100% statement coverage, too). M Computing Coverage For Java, use jcoverage or like tools. Coverage is computed automatically while the program executes Requires instrumentation at compile time With GCC, for instance, use options -ftest-coverage -fprofile-arcs After execution, coverage tool assesses and summarizes results With GCC, use gcov source-file to obtain readable.gcov file emo This is the output of the GCOV coverage tool for cgi_decode. Each statement (each line) is annotated with the number of executions so far. Zero executions is suspicious and would be marked by ##### ; the tag stands for lines without executable code.

See the package cgi_decode.zip on the course page for instructions on how to do this yourself. emo Test Path interior CSAJ Branch Statement is a simple criterion for assessing the adequacy of a test suite but there are many more such criteria. Statement Test Path interior CSAJ Branch As an example, consider branch, which is a criterion that statement. n other words, if the branch criterion is satisfied by a pair program, test suite, so is the statement criterion for the same pair. Statement

101% 76% 51% 25% 0% 100% Coverage if (c == '%') { *dptr = *eptr; F B A C G +%0d+%4j E Why is branch useful? Assume block F were missing (= a defect). Then, we could achieve 100% statement coverage without ever triggering the defect. M A +%0d+%4j f we focus on whether branches have been taken, though, we get a different picture. while (*eptr) { B C if (c == '%') { E *dptr = *eptr; F G M 100% A +%0d+%4j ere, we d find that the test case executes only 7 out of 8 branches, or 87%. 75% 50% 25% 0% 87% Coverage if (c == '%') { *dptr = *eptr; F B C G E M

100% 101% 100% A +%0d+%4j abc With another test case, we can cover this remaining branch and find the defect. 75% 76% 50% 51% 25% 0% 87% Coverage if (c == '%') { *dptr = *eptr; F B C G E M Branch Testing (from Pezze + Young, Software Testing and Analysis, Chapter 12) Adequacy criterion: each branch in the CFG must be executed at least once Coverage: # executed branches # branches Subsumes statement criterion because traversing all edges implies traversing all nodes Most widely used criterion in industry Condition Testing Consider the defect (digit_high == 1 digit_low == -1) // should be -1 Branch adequacy criterion can be achieved by changing only digit_low i.e., the defective sub-expression may never determine the result Faulty sub-condition is never tested although we tested both outcomes of the branch

Condition Testing Key idea: also cover individual conditions in compound boolean expression e.g., both parts of digit_high == 1 digit_low == -1 Condition Testing Adequacy criterion: each basic condition must be evaluated at least once Coverage: # truth values taken by all basic conditions 2 * # basic conditions Example: test+%9k%k9 100% basic condition coverage but only 87% branch coverage Test Path interior CSAJ Branch The basic condition criterion is not comparable with branch or statement coverage criteria neither implies () the other. Statement

Test Path interior CSAJ Branch The idea here is to cover both branch and by covering all conditions and all decisions. That is, every sub-condition must be true and false, but the entire condition just as well. Statement Test Path interior CSAJ Branch Another idea might be simply to test all possible combinations. This is called compound. Statement Conditions Assume (((a b) c) d) e) We need 13 tests to cover all possible combinations n general case, we get a combinatorial explosion Test Case a b c d e (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) An alternative approach that can be satisfied with the

Test Path interior CSAJ Branch The combinatorial explosion is the reason why compound is a theoretical, rather than a practical criterion. Statement Test Path interior CSAJ Branch A possible compromise is MCC or Modified Condition/ecision Coverage. Statement MCC Testing Modified Condition ecision Coverage Key idea: Test important combinations of conditions, avoiding exponential blowup A combination is important if each basic condition is shown to independently affect the outcome of each decision

MCC Testing Modified Condition ecision Coverage For each basic condition C, we need two test cases T1 and T2 Values of all evaluated conditions except C are the same condition as a whole evaluates to for T1 and false for T2 A good balance of thoroughness and test size (and therefore widely used) MCC Testing Modified Condition ecision Coverage Assume (((a b) c) d) e) We need six tests to cover MCC combinations ve been numbered for easy comparison with the previous table a b c d e ecision (1) (2) (3) (6) (11) (13) The values underlined in the table independently affect the out Underlined values independently affect the outcome of the decision. Note that the same test case can cover the values of several basic conditions. For example, test case (1) covers value for the basic conditions a, c and e. Note also that this is not the only possible set of test cases to satisfy the criterion; a different selection of boolean combinations could be equally effective. Path Testing beyond individual branches Key idea: explore sequences of branches in control flow Many more paths than branches calls for compromises

Test Path interior CSAJ Branch Statement Test Path interior CSAJ Branch For one thing, there is general path, i.e. covering all paths in the program. Since loops are unbounded, this is generally not feasible and therefore just a theoretical criterion. ts advantage, though, is that it almost all criteria. Statement Test Path interior CSAJ Branch interior groups together paths that differ only in the subpath they follow when repeating the body of a loop. n other words, we follow each path in the CFG up to the first repeated node. Statement

nterior Adequacy for cgi_decode The graph at the right shows the paths that must be covered in the control flow graph at the left, using the boundary interior adequacy criiterion. Original CFG Paths to be covered ssues c1? c2? c3? c4? s1 s2 s3 s4 The number of paths may still grow exponentially n this example, there are 2 4 = 16 paths Forcing paths may be infeasible or even impossible if conditions are not independent Test Path interior CSAJ Branch Therefore, boundary interior belongs more to the theoretical criteria. Statement

Test Path interior CSAJ Branch Another alternative is loop boundary which forces constraints on how loops are to be executed. This is a practical criterion. Statement oop Adequacy A test suite satisfies the loop boundary adequacy criterion if for every loop : There is a test case which iterates zero times There is a test case which iterates once There is a test case which iterates more than once Typically combined with other adequacy criteria such as MCC This is a variant of the boundary/interior criterion that treats loop boundaries similarly but is less stringent with respect to other differences among paths 0 1 2 B A C a abc With these three test cases, we obtain loop boundary adequacy for the cgi_decode main loop. if (c == '%') { E *dptr = *eptr; F G M

Test Path interior CSAJ Branch Another alternative is loop boundary which forces constraints on how loops are to be executed. Statement Test Path interior CSAJ Branch CSAJ is a generalization over branch and statement coverage. Statement CSAJ Adequacy Testing all paths up to a fixed length CSAJ = inear Code Sequence And Jump A CSAJ is a sequential subpath in the CFG starting and ending in a branch Considering the exponential blowup in sequences of conditional statements (even when not in loops), we might choose to consider only sub-sequences of a given length. This is what CSAJ gives us --- essentially considering full path coverage of (short) sequences of decisions. CSAJ length corresponds to 1 statement coverage 2 branch coverage n coverage of n consecutive CSAJs path coverage

Test Path interior CSAJ Branch And this is the summary of structural techniques. Statement Weyuker s ypothesis Established by a number of studies done by E. Weyuker at AT&T. Any explicit relationship between coverage and error detection would mean that we have a fixed distribution of errors over all statements and paths, which is clearly not the case. The adequacy of a coverage criterion can only be intuitively defined. Satisfying Sometimes criteria may not be satisfiable: Statements may not be executed because of defensive programming or code reuse Conditions may not be satisfiable because of interdependent conditions Paths may not be executable because of interdependent decisions

Satisfying Reaching specific code can be very hard! Even the best-designed, best-maintained systems may contain unreachable code A large amount of unreachable code/paths/ conditions is a serious maintainability problem Solutions: allow coverage less than 100%, or require justification for exceptions More Testing Object-oriented e,g, Every transition in the object s FSM must be covered or Every method pair in the object s FSM must be covered nterclass e.g, Every interaction between two objects must be covered ata flow e.g., Every definition-use pair of a variable must be covered if (c == '%') { B A C definitions E ata flow is based on the observation that computing the wrong value leads to a failure only when that value is subsequently used. A typical data flow criterion is therefore that the tests must exercise every pair (definition, uses) of a variable (such as ok in this example). *dptr = *eptr; F G uses M

Summary