Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Testing Syntax-based Testing. Syntax Coverage Four Structures for Modeling Software Graphs Logic Input Space Syntax Use cases Specs Design Source.

Similar presentations


Presentation on theme: "Software Testing Syntax-based Testing. Syntax Coverage Four Structures for Modeling Software Graphs Logic Input Space Syntax Use cases Specs Design Source."— Presentation transcript:

1 Software Testing Syntax-based Testing

2 Syntax Coverage Four Structures for Modeling Software Graphs Logic Input Space Syntax Use cases Specs Design Source Applied to DNF Specs FSMs Source Input Models Integ Source

3 White-box testing white-box testing is the process of carefully and methodically reviewing the software design, architecture, or code for bugs without executing it. Unfortunately, white-box testing is rarely done in practice (unlike black- box testing).

4 Applying Syntax-based Testing to Programs Syntax-based criteria originated with programs and have been used most with programs BNF criteria are most commonly used to test compilers Mutation testing criteria are most commonly used for unit testing and integration testing of classes

5 5 Instantiating Grammar-Based Testing Grammar-Based Testing Program-basedIntegrationModel-BasedInput-Based Compiler testing Valid and invalid strings Grammar String mutation Program mutation Valid strings Mutants are not tests Must kill mutants Input validation testing XML and others Valid strings Grammar Test how classes interact Valid strings Mutants are not tests Must kill mutants Includes OO String mutation FSMs Model checking Valid strings Traces are tests String mutation Input validation testing XML and others Invalid strings No ground strings Mutants are tests String mutation 5.2

6 6 BNF Testing for Compilers (5.2.1) Testing compilers is very complicated –Millions of correct programs ! –Compilers must recognize and reject incorrect programs BNF criteria can be used to generate programs to test all language features that compilers must process

7 BNF Grammars Stream ::= action* action ::= actG | actB actG ::= “G” s n actB ::= “B” t n s ::= digit 1-3 t ::= digit 1-3 n ::= digit 2 “.” digit 2 “.” digit 2 digit ::= “0” | “1” | “2” | “3” | “4” | “5” | “6” | “7” | “8” | “9” Non-terminals Terminals Production rule Start symbol

8 © Ammann & Offutt 8 Example Ground String G 22 08.01.90 B 18 06.27.94 Mutation Operators Exchange actG and actB Exchange actG and actB Replace digits with all other digits Replace digits with all other digits Mutants using MOC B 22 08.01.90 B 19 06.27.94 Mutants using MPC B 22 08.01.90 G 18 06.27.94 G 12 08.01.90 B 11 06.27.94 G 32 08.01.90 B 12 06.27.94 G 42 08.01.90 B 13 06.27.94 G 52 08.01.90 B 14 06.27.94 … … … … Stream ::= action* action ::= actG | actB actG ::= “G” s n actB ::= “B” t n s ::= digit 1-3 t ::= digit 1-3 n ::= digit 2 “.” digit 2 “.” digit 2 digit ::= “0” | “1” | “2” | “3” | “4” | “5” | “6” | “7” | “8” | “9” Grammar

9 Mutation as Grammar-Based Testing Grammar-based Testing UnMutated Derivations (valid strings) Mutated Derivations (invalid strings) Grammar Mutation (invalid strings) Ground String Mutation Invalid Strings Valid Strings Generic coverage criteria can now be defined

10 Program-based Grammars The original and most widely known application of syntax-based testing is to modify programs Operators modify a ground string (program under test) to create mutant programs Mutant programs must compile correctly (valid strings) Mutants are not tests, but used to find tests Once mutants are defined, tests must be found to cause mutants to fail when executed This is called “killing mutants” 10

11 Mutation Testing Ground string: A string in the grammar –The term “ground” is used as a reference to algebraic ground terms Mutation Operator : A rule that specifies syntactic variations of strings generated from a grammar Mutant : The result of one application of a mutation operator –A mutant is a string

12 Mutant operators: Examples Mutant operatorIn PIn mutant Variable replacementz=x*y+1;x=x*y+1; z=x*x+1; Relational operator replacement if (x<y)if(x>y) if(x<=y) Off-by-1z=x*y+1;z=x*(y+1)+1; z=(x+1)*y+1; Replacement by 0z=x*y+1;z=0*y+1; z=0; Arithmetic operator replacement z=x*y+1;z=x*y-1; z=x+y-1;

13 What is program mutation?  P’ is known as a mutant of P.  There might be a test t in T such that P(t)≠P’(t). In this case we say that t distinguishes P’ from P. Or, that t has killed P’.  There might be not be any test t in T such that P(t)≠P’(t). In this case we say that T is unable to distinguish P and P’. Hence P’ is considered live in the test process.

14 Killing Mutants If mutation operators are designed well, the resulting tests will be very powerful Different operators must be defined for different programming languages and goals Testers can keep adding tests until all mutants have been killed –Dead mutant : A test case has killed it –Stillborn mutant : Syntactically illegal –Trivial mutant : Almost every test can kill it –Equivalent mutant : No test can kill it (equivalent to original program) Given a mutant m  M for a ground string program P and a test t, t is said to kill m if and only if the output of t on P is different from the output of t on m.

15 Error detection using mutation  Consider the following function foo that is required to return the sum of two integers x and y. int foo(int x, y){ return (x-y); }

16 Error detection using mutation  Now suppose that foo has been tested using a test set T that contains two tests: T={ t1:, t2: }  First note that foo behaves perfectly fine on each test in, i.e. foo returns the expected value for each test case in T. Also, T is adequate with respect to all control and data flow based test adequacy criteria.

17 Error detection using mutation  Note that M1 is obtained by replacing the - operator by a + operator, M2 by replacing y by 0, and M3 by replacing x by 0. int foo(int x, y){ return (x+y); } M1: int foo(int x, y){ return (x-0); } M2: int foo(int x, y){ return (0+y); } M3: Let us evaluate the adequacy of T using mutation. Suppose that the following three mutants are generated from foo.

18 Error detection using mutation Next we execute each mutant against tests in T until the mutant is distinguished or we have exhausted all tests. Here is what we get. Test (t)foo(t)M1(t)M2(t)M3(t) t11110 t2 0 Live Killed T={ t1:, t2: }

19 Questions About Mutation Should more than one operator be applied at the same time ? –Should a mutated string contain one mutated element or several? –Almost certainly not – multiple mutations can interfere with each other –Extensive experience with program-based mutation indicates not Mutation operators exist for several languages –Several programming languages (Fortran, Lisp, Ada, C, C++, Java) –Specification languages (SMV, Z, Object-Z, algebraic specs) –Modeling languages (Statecharts, activity diagrams) –Input grammars (XML, SQL, HTML)

20 20 Mutation testing Consider the following program P 1. main(argc,argv) 2. int argc, r, i; 3. char *argv[]; 4. { r = 1; 5. for i = 2 to 3 do 6. if (atoi(argv[i]) > atoi(argv[r])) r = i; 7. printf(“Value of the rank is %d \n”, r); 8. exit(0); } Test Case 1: input: 1 2 3 output: Value of the rank is 3 Test Case 2: input: 1 2 1 output: Values of the rank is 2 Test Case 3: input: 3 1 2 output: Value of the rank is 1 Mutant 1: Change line 5 to for i = 1 to 3 do Mutant 2: Change line 6 to if (i > atoi(argv[r])) r = i; Mutant 3: Change line 6 to if (atoi(argv[i]) >= atoi(argv[r])) r = i; Mutant 4: Change line 6 to if (atoi(argv[r]) > atoi(argv[r])) r = i; Execute modified programs against the test suite, you will get the results: Mutants 1 & 3: Programs will pass the test suite, i.e., mutants 1 & 3 are not killable Mutant 2: Program will fail test cases 2 Mutant 1: Program will fail test case 1 and test cases 2 Mutation score is 50%, assuming mutants 1 & 3 non-equivalent

21 Logic Mutation Testing Process 1) Systematically create program variations (mutants) each containing a single typical logic fault if (a && b)  if (a || b) 2) For each mutant, find an input that distinguishes the original program from the mutant program (killing) - a && b and a || b evaluate to different truth values

22 Program-based Grammars Original Method int Min (int A, int B) { int minVal; minVal = A; if (B < A) { minVal = B; } return (minVal); } // end Min With Embedded Mutants int Min (int A, int B) { int minVal; minVal = A; ∆ 1 minVal = B; if (B < A) ∆ 2 if (B > A) ∆ 3 if (B < minVal) { minVal = B; ∆ 4 Bomb (); ∆ 5 minVal = A; ∆ 6 minVal = failOnZero (B); } return (minVal); } // end Min 6 mutants Each represents a separate program Replace one variable with another Changes operator Immediate runtime failure … if reached Immediate runtime failure if B==0 else does nothing

23 Syntax-Based Coverage Criteria 1) Strongly Killing Mutants: Given a mutant m  M for a program P and a test t, t is said to strongly kill m if and only if the output of t on P is different from the output of t on m 2) Weakly Killing Mutants: Given a mutant m  M that modifies a location l in a program P, and a test t, t is said to weakly kill m if and only if the state of the execution of P on t is different from the state of the execution of m immediately on t after l

24 Weak Mutation Example The complete test specification to kill mutant 1: (A = 5, B = 3) will weakly kill mutant 1, but not strongly minVal = A; ∆ 1 minVal = B; if (B < A) minVal = B; Mutant 1 in the Min( ) example is:

25 Equivalent Mutation Example Mutant 3 in the Min() example is equivalent: minVal = A; if (B < A) ∆ 3 if (B < minVal) The infection condition is “(B < A) != (B < minVal)” However, the previous statement was “minVal = A” –Substituing, we get: “(B < A) != (B < A)” Thus no input can kill this mutant

26 1 boolean isEven (int X) 2 { 3 if (X < 0) 4 X = 0 - X; ∆ 4 X = 0; 5 if (float) (X/2) == ((float) X) / 2.0 6 return (true); 7 else 8 return (false); 9 } Strong Versus Weak Mutation (X = -6) will kill mutant 4 under weak mutation

27 27 Automated steps Testing Programs with Mutation Input test method Prog Create mutants Run T on P Run mutants: schema-based weak selective Eliminate ineffective TCs Generate test cases Run equivalence detector Threshold reached ? Define threshold no P (T) correct ? yes Fix P no

28 Mutation Operators for Java Each occurrence of one of the arithmetic operators +, -,*, /, and % is replaced by each of the other operators. In addition, each is replaced by the special mutation operators leftOp, and rightOp. 2. AOR –– Arithmetic Operator Replacement: Each arithmetic expression (and subexpression) is modified by the functions abs(), negAbs(), and failOnZero(). 1. ABS –– Absolute Value Insertion: Each occurrence of one of the relational operators (, ≥, =, ≠) is replaced by each of the other operators and by falseOp and trueOp. 3. ROR –– Relational Operator Replacement:

29 Mutation Operators for Java (2) Each occurrence of one of the logical operators (and - &&, or - ||, and with no conditional evaluation - &, or with no conditional evaluation - |, not equivalent - ^) is replaced by each of the other operators; in addition, each is replaced by falseOp, trueOp, leftOp, and rightOp. 4. COR –– Conditional Operator Replacement: 5. SOR –– Shift Operator Replacement: Each occurrence of one of the shift operators >, and >>> is replaced by each of the other operators. In addition, each is replaced by the special mutation operator leftOp. Each occurrence of one of the logical operators (bitwise and - &, bitwise or - |, exclusive or - ^) is replaced by each of the other operators; in addition, each is replaced by leftOp and rightOp. 6. LOR –– Logical Operator Replacement:

30 Mutation Operators for Java (3) Each occurrence of one of the assignment operators (+=, -=, *=, /=, %=, &=, |=, ^=, >=, >>>=) is replaced by each of the other operators. 7. ASR –– Assignment Operator Replacement: 8. UOI –– Unary Operator Insertion: Each unary operator (arithmetic +, arithmetic -, conditional !, logical ~) is inserted in front of each expression of the correct type. Each unary operator (arithmetic +, arithmetic -, conditional !, logical~) is deleted. 9. UOD –– Unary Operator Deletion:

31 Mutation Operators for Java (4) Each variable reference is replaced by every other variable of the appropriate type that is declared in the current scope. 10. SVR –– Scalar Variable Replacement:

32 Binary search example int search ( int key, int [] elemArray) { int bottom = 0; int top = elemArray.length - 1; int mid; int result = -1; while ( bottom <= top ) { mid = (top + bottom) / 2; if (elemArray [mid] == key) { result = mid; return result; } // if part else { if (elemArray [mid] < key) bottom = mid + 1; else top = mid - 1; } } //while loop return result; } // search


Download ppt "Software Testing Syntax-based Testing. Syntax Coverage Four Structures for Modeling Software Graphs Logic Input Space Syntax Use cases Specs Design Source."

Similar presentations


Ads by Google