Testing Part 2 1 Three Important Testing Questions How shall we - - PowerPoint PPT Presentation

testing part 2
SMART_READER_LITE
LIVE PREVIEW

Testing Part 2 1 Three Important Testing Questions How shall we - - PowerPoint PPT Presentation

Testing Part 2 1 Three Important Testing Questions How shall we generate/select test cases? Did this test execution succeed or fail? How do we know when weve tested enough? 65 1. How do we know when weve tested enough?


slide-1
SLIDE 1

Testing Part 2

1

slide-2
SLIDE 2

Three Important Testing Questions

  • How shall we generate/select test

cases?

  • Did this test execution succeed or fail?
  • How do we know when we’ve tested

enough?

65

slide-3
SLIDE 3
  • 1. How do we know when we’ve

tested enough?

Test Coverage Measures

66

slide-4
SLIDE 4

Structural Coverage Testing

  • Idea

– Code that has never been executed likely has bugs

  • At least the test suite is clearly not complete
  • This leads to the notion of code coverage

– Divide a program into elements (e.g., statements) – Define the coverage of a test suite to be # of elements executed by suite # of elements in program

67

slide-5
SLIDE 5

Types of Program Elements

  • Selection of test suite is based on some

elements in the code

  • Assumption: Executing the faulty

element is a necessary condition for revealing a fault

  • Several types of elements

– Control flow: statement, branch, path – Condition: simple, multiple – Loop – Dataflow – Fault based (mutation) – …

68

slide-6
SLIDE 6

Control Flow Graphs: The One Slide Tutorial

  • A graph
  • Nodes are basic blocks
  • statements
  • Edges are transfers of control between basic blocks

X := 3 Y := Z + W Y := 0 A := 2 * 3 B > 0

X := 3; if (B > 0) Y := 0; else Y := Z + W; A = 2 * 3;

69

slide-7
SLIDE 7

Control Flow Graph

void testme1(int x) { int j = 0; for (j=0; j < 2; j++) { if (x==j) { printf(“Good\n”); } } x = j; }

  • A graph
  • Nodes are basic blocks
  • statements
  • Edges are transfers of control between basic blocks

70

slide-8
SLIDE 8

Control Flow Graph

void testme1(int x) { int j =0; for (j=0; j < 2; j++) { if (x==j) { printf(“Good\n”); } } x = j; }

j=0 j < 2 x==j printf j++ x = j

71

slide-9
SLIDE 9

Statement Coverage

  • Test requirements: Statements in a

program

# of executed statements # of statements in the program

72

slide-10
SLIDE 10

Statement Coverage in Practice

  • The good old days: (Stucki 1973)

– Only about 1/3 of NASA statements were executed under test before software was released

  • Better results:

– Microsoft reports 80-90% statement coverage – Boeing must get 100% statement coverage (feasible?) for all software

  • 100% can be hard or impossible (why?)

74

slide-11
SLIDE 11

Statement Coverage: Example

  • Test requirements

– Nodes 3, …, 9

  • Test cases

– (x = 20, y = 30)

73

Any problems with this example?

slide-12
SLIDE 12

Statement Coverage: Example

  • Test requirements

– Nodes 3, …, 9

  • Test cases

– (x = 20, y = 30)

  • Such test does not

reveal the fault at statement 7

  • To reveal it, we

need to traverse edge 4-7 => Branch Coverage

75

slide-13
SLIDE 13

Branch Coverage

  • Test requirements: Branches in a

program

# of executed branches # of branches in the program

76

slide-14
SLIDE 14

Branch Coverage: Example

  • Test requirements

– Edges 4-6, Edges 4-7

  • Test cases

– (x = 20, y = 30) – (x = 0, y = 30)

77

slide-15
SLIDE 15

Branch Coverage: Example

  • 1. main() {

2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 0; 9. if (y>0) 10. w = y / z; 11. 12. }

  • Branch Coverage
  • Test Cases

– (x = 1, y = 22) – (x = 0, y = -10)

  • Is the test suite

adequate for branch coverage?

78

slide-16
SLIDE 16

Branch Coverage: Example

  • 1. main() {

2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 0; 9. if (y>0) 10. w = y / z; 11. 12. }

  • Branch Coverage
  • Test Cases

– (x = 1, y = 22) – (x = 0, y = -10)

  • Is the test suite

adequate for branch coverage?

  • Yes, but it does not

reveal the fault at statement 10

  • Test case (x = 0, y = 22)

– Reveals fault

79

slide-17
SLIDE 17

Data Flow Coverage

  • Test requirements: Def-use pairs in a

program

# of executed def-use pairs # of def-use pairs in the program

80

slide-18
SLIDE 18

Data Flow Coverage: Example

  • 1. main() {

2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 0; 9. if (y>0) 10. w = y / z; 11. 12. }

  • Test Requirements:

– DU pairs 6-10, 8-10

  • Test Cases

– (x = 1, y = 22) – (x = 0, y = 10)

  • Reveals fault

81

slide-19
SLIDE 19

Data Flow Coverage: Example

  • 1. main() {

2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 1; 9. if (y>0)

  • 10. w = y / z;
  • 11. else

12. assert(0);

  • 13. }
  • Test Requirements:

– DU pairs 6-10, 8-10

  • Test Cases

– (x = 1, y = 22) – (x = 0, y = 10)

  • Is the test suite

adequate for data flow coverage?

82

slide-20
SLIDE 20

Data Flow Coverage: Example

  • 1. main() {

2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 1; 9. if (y>0)

  • 10. w = y / z;
  • 11. else

12. assert(0);

  • 13. }
  • Test Requirements:

– DU pairs 6-10, 8-10

  • Test Cases

– (x = 1, y = 22) – (x = 0, y = 10)

  • Is the test suite adequate

for data flow coverage?

  • Yes, but it does not reveal

the fault at statement 12

  • Test case (x = 1, y = -1)

– Reveals fault

83

slide-21
SLIDE 21

All Path Coverage: Example

1. main() { 2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 1; 9. if (y>0) 10. w = y / z; 10. else 11. assert(0); 12. 13.

  • 14. }
  • Test Requirements:

– 4 paths

  • Test Cases

– (x = 1, y = 22) – (x = 0, y = 10) – (x = 1, y = -22) – (x = 1, y = -10)

84

slide-22
SLIDE 22

All Path Coverage: Example

1. main() { 2. int x, y, z, w; 3. read(x); 4. read(y); 5. if (x != 0) 6. z = x + 10; 7. else 8. z = 1; 9. if (y>0) 10. w = y / z; 10. else 11. w = 0; 12. 13.

  • 14. }
  • Test Requirements:

– 4 paths

  • Test Cases

– (x = 1, y = 22) – (x = 0, y = 10) – (x = 1, y = -22) – (x = 1, y = -10)

  • Faulty if x = -10

– Structural coverage may not reveal this error

86

slide-23
SLIDE 23

Pitfalls of Coverage

status = perform_operation(); if (status == FATAL_ERROR) exit(3);

  • Coverage says the exit is never taken
  • Straightforward to fix

– Add a case with a fatal error

87

slide-24
SLIDE 24

Example

status = perform_operation(); if (status == FATAL_ERROR) exit(3);

  • Coverage says the exit is never taken
  • Straightforward to fix

– Add a case with a fatal error

  • But are there other error conditions that are not

checked in the code?

– Coverage does not help with faults of omission

88

slide-25
SLIDE 25

Code Coverage (Cont.)

  • Code coverage has proven value

– It’s a real metric, though far from perfect

  • But 100% coverage does not mean no bugs

– Many bugs lurk in corner cases – E.g., a bug visible after loop executes 1,025 times

  • And 100% coverage is almost never achieved

– Products ship with < 60% coverage – High coverage may not even be economically desirable

  • May be better to devote more time to tricky parts with good

coverage

89

slide-26
SLIDE 26

Coverage: the Bad assumptions Logical Fallacies

  • TRUE If low coverage then poor tests;

Not low coverage, therefore not poor tests

  • TRUE If good tests then high coverage;

High coverage, therefore good tests

90

slide-27
SLIDE 27

Coverage: the Bad assumptions Logical Fallacies

  • TRUE If low coverage then poor tests;

FALSE Not low coverage, therefore not poor tests

  • TRUE If good tests then high coverage;

FALSE High coverage, therefore good tests

91

slide-28
SLIDE 28

Using Code Coverage

  • Code coverage helps identify weak test

suites

  • Tricky bits with low coverage are a

danger sign

  • Areas with low coverage suggest

something is missing in the test suite

92

slide-29
SLIDE 29

The Lesson

  • Code coverage can’t complain about

missing code

– The case not handled

93

slide-30
SLIDE 30

Structural Coverage in Practice

  • Statement and sometimes edge or condition

coverage is used in practice

– Simple lower bounds on adequate testing

  • Additional control flow heuristics sometimes used

– Loops (never, once, many), combinations of conditions

  • See “How to Misuse Code Coverage” in course

schedule

94

slide-31
SLIDE 31

Standard Testing Questions

  • How shall we generate/select test

cases?

  • Did this test execution succeed or fail?
  • How do we know when we’ve tested

enough?

95

slide-32
SLIDE 32
  • 2. Was this test execution correct?

96

slide-33
SLIDE 33

What is an Oracle?

  • Oracle = alternative realization of the specification
  • Examples of oracles

– The “eyeball oracle”

  • Expensive, not dependable, lack of automation

– A prototype, or sub-optimal implementation

  • E.g., bubble-sort as oracle for quick sort

– A manual list of expected results

Program Oracle input

  • utput

correct

  • utput

compare

97

slide-34
SLIDE 34

Record-and-Replay Oracles

  • Record prior runs
  • Test recording is usually very fragile

– Breaks if environment changes anything – E.g., location, background color of textbox

  • More generally, automation tools cannot generalize

– They literally record exactly what happened – If anything changes, the test breaks

  • A hidden strength of manual testing

– Because people are doing the tests, ability to adapt tests to slightly modified situations is built-in

98

slide-35
SLIDE 35

Result Checking

  • Easy to check the result of some

algorithms

– E.g., computing roots of polynomials, vs. checking that the result is correct – E.g., executing a query, vs. checking that the results meet the conditions

  • Not easy to check that you got all results

though ! Program input

  • utput

check

99

slide-36
SLIDE 36

Assertions

  • Use assert(…) liberally

– Documents important invariants – Makes your code self-checking

  • reduces propagation from fault to failure

– And does it on every execution !

  • for a performance price

– You still have to worry about coverage

  • May need to write functions that check

invariants

  • Opinion: Most programmers don’t use assert

enough

100

slide-37
SLIDE 37

Standard Testing Questions

  • How shall we generate/select test

cases?

  • Did this test execution succeed or fail?
  • How do we know when we’ve tested

enough?

101

slide-38
SLIDE 38
  • 3. How Shall We Generate/

Select Tests?

Automatic Test Generation

102

slide-39
SLIDE 39

Fuzz Testing

  • What is Fuzz Testing?

– Throw random data at an app – See what breaks

103

slide-40
SLIDE 40

Bugs Found Through Fuzzing

  • About ¼ of Unix utilities crash when

fed random input strings!!

  • Microsoft estimates 20-25% of bugs

found this way

  • Examples

– Microsoft JPEG parsing error – Linksys WRT54G wireless router crack – Device Driver crashes – Skype remote DOS from heap overflow

104

slide-41
SLIDE 41

Offjce 2007: 4 bugs, 3 hours, 7 lines of python fuzzer

http://www.pakwarez.com/showthread.php? 1813-Multiple-Microsoft-Offjce-Security- Vulnerabilities + Unspecified Overflow in word 2007

  • Crash in wwlib.dll . Code execution is not

trivial.

+ Word 2007 CPU exhaustion DOS

  • CPU shoots up to 100 %.

+ Word 2007 CPU exhaustion DOS + ding

  • CPU shoots up to 100 %, and windows

goes .ding!.

+ Heap overflow in Windows HLP files

  • Funky heap overflow crash.

105

slide-42
SLIDE 42

Random Bugs

  • What sort of bugs does fuzz testing find?

– Bufger overruns – Format string errors – Wild pointers/array out of bounds – Signed/unsigned characters – Failure to handle return codes – Race conditions

106

slide-43
SLIDE 43

World’s Simplest Fuzzer

  • while [ 1 ]; do cat /dev/urandom | nc -vv target port; done

– (Sutton, 2007)

  • Can be hard to figure out exactly what

caused a crash

– We’ll see a technique later

107

slide-44
SLIDE 44

Why Fuzzers Work?

  • Test engineers try to generate bad

inputs

– but human generated test cases tend to contain fewer tests than a fuzzer can produce.

  • Test engineers may make implicit

assumptions input

– an automated, brainless fuzzer will just try anything

108

slide-45
SLIDE 45

Fuzzing Techniques

  • Dumb fuzzing

– sends random bytes of data to a program and see what, if anything, happens

  • Smart fuzzing

– extends dumb fuzzing with more domain specific data – A fuzzer targeted at web applications might generate GET and POST queries using (and abusing) the variables that the form or page submits as well as adding in some random variables and values. – A fuzzer targeting a web browser might generate random input that conformed to HTML syntax, with random tags and attributes as well as abusing the defined tags.

  • A combination of both dumb and smart fuzzing is

likely the best approach.

109

slide-46
SLIDE 46

Fuzz Generation: String Heuristics

  • Very long strings, even of single character
  • Strings of high-ASCII
  • Non-alphanumerics:

– !@#$%^&*()_-+=:;'"

  • Unicode:

– non-ASCII malformed surrogate pairs, ASCII encoded in several bytes, etc.

  • Directory traversal:

– .., ../, ../.., ../../.., etc. – Sendmail vulnerability “///////…. /”, “<><><>…<>”

  • Format string: %n%n%n%n %s%n%s%n

110

slide-47
SLIDE 47

Fuzz + Enumeration

  • Sometimes the strings come from an

underlying “grammar”

– In a compiler

  • Mix fuzzing and enumeration

– Enumerate strings from the grammar, with “holes” – Fill holes with fuzz – Command injection: “ls *”, “SELECT FROM”

  • Useful in compiler testing

111

slide-48
SLIDE 48

Web App Heuristics: URLs

  • Directory traversal
  • Fuzz file extensions in

particular: .htm, .html, etc.

  • Long URLs
  • Query strings, names and values
  • Malformed URLs with unescaped

characters

112

slide-49
SLIDE 49

Open Source Fuzzers

  • http://www.infosecinstitute.com/blog/2005/12/

fuzzers-ultimate-list.html

  • (L)ibrary (E)xploit API - lxapi - A collection of

python scripts for fuzzing

  • … many more
  • Original Fuzz tool by Bart Miller:
  • http://pages.cs.wisc.edu/~bart/fuzz/fuzz.html

113

slide-50
SLIDE 50

Comments About Fuzz Testing

  • Difgers from Targeted Testing

– May well miss dangerous paths – Will take paths no logical person would ever consider – Tests vastly more conditions and paths than a human could – Like unit testing, usually starts from a clean

  • slate. Thus misses multicondition bugs

– A supplement to traditional boundary value analysis and other human driven testing;

  • not a replacement

114

slide-51
SLIDE 51

Limitations of Fuzz Testing

  • Access control
  • Checksums and file verification
  • Grammars
  • Multistep bugs

115

slide-52
SLIDE 52

Limitations of Fuzzing

  • Probability of

reaching an error can be astronomically low test_me(int x){ if(x==94389){ ERROR; } } Probability of hitting ERROR = 1/232

116

slide-53
SLIDE 53

Symbolic Execution

  • Use symbolic values for input variables
  • Execute the program symbolically on

symbolic input values

  • Collect symbolic path constraints
  • Use constraint solver to generate test

inputs for each execution path

  • Lots of recent work on constraint solving

– Well-engineered tools available (Z3, Yices) – Unfortunately, cannot cover in this class

117

slide-54
SLIDE 54

Computation Tree: Execution Paths of a Program

  • Can be seen as a binary tree

with possibly infinite depth

– Computation tree

  • Each node represents the

execution of a “if then else” statement

  • Each edge represents the

execution of a sequence of non-conditional statements

  • Each path in the tree

represents an equivalence class of inputs

1 1 1 1 1 1 1

118

slide-55
SLIDE 55

Example of Computation Tree

void test_me(int x, int y) { if(2*x==y){ if(x != y+10){ printf(“I am fine here”); } else { printf(“I should not reach here”); ERROR; } } } 2*x==y x!=y+10 N Y N Y ERROR

119

slide-56
SLIDE 56

Active Checking for Errors

Divide by 0 Error x = 3 / i; Bufger Overflow a[i] = 4;

120

slide-57
SLIDE 57

Active Checking for Errors

Divide by 0 Error if (i !=0) x = 3 / i; else ERROR; Bufger Overflow if (0<=i && i < a.length) a[i] = 4; else ERROR; Key: Add Checks Automatically and Try to Cover all Branches

121

slide-58
SLIDE 58

Concrete Execution

int x = read(); int y = read(); int t; t = x; x = x + y; if (x > y) { y = 2*t; if (x+1 == y) { assert(false); } }

122

slide-59
SLIDE 59

Concrete Execution

int x = read(); int y = read(); int t; t = x; x = x + y; if (x > y) { y = 2*t; if (x+1 == y) { assert(false); } } x = 4 y = 9 t = 4 x = 13 (13 > 9) y = 8 (14 == 8) END

123

slide-60
SLIDE 60

Symbolic Execution

int x = read(); int y = read(); int t; t = x; x = x + y; if (x > y) { y = 2 * t; if (x+1 == y) { assert(false); } }

(true | x = x0 ) (true | x = x0,y=y0) (true | x = x0,y=y0,t=x0) (true | x = x0+y0,y=y0,t=x0) x0+y0 > y0 (x0+y0<= y0 | x = x0+y0,y=y0,t=x0) (x0+y0> y0 | x = x0+y0,y=2x0,t=x0) x0+y0 + 1 == 2x0 (x0 +y0> y0, x0 + y0 + 1 == 2x0 | x = x0+y0,y=2x0,t=x0) (x0 +y0> y0, x0 + y0 + 1 ≠ 2x0 | x = x0+y0,y=2x0,t=x0)

124

slide-61
SLIDE 61

Symbolic Execution

int x = read(); int y = read(); int t; t = x; x = x + y; if (x > y) { y = 2 * t; if (x+1 == y) { assert(false); } }

(true | x = x0 ) (true | x = x0,y=y0) (true | x = x0,y=y0,t=x0) (true | x = x0+y0,y=y0,t=x0) x0+y0 > y0 (x0+y0<= y0 | x = x0+y0,y=y0,t=x0) (x0+y0> y0 | x = x0+y0,y=2x0,t=x0) x0+y0 + 1 == 2x0 (x0 +y0> y0, x0 + y0 + 1 == 2x0 | x = x0+y0,y=2x0,t=x0) (x0 +y0> y0, x0 + y0 + 1 ≠ 2x0 | x = x0+y0,y=2x0,t=x0) Solve constraint Solution: x = 0, y=0 Solve constraint Solution: x = 1, y=9 Solve constraint Solution: x = 2, y=1

125

slide-62
SLIDE 62

Concolic Approach

  • Combine concrete and symbolic execution for

unit testing

– DART: Directed Automated Random Testing – Concrete + Symbolic = Concolic

  • Why would you do this?

126

slide-63
SLIDE 63

Concolic Approach

  • Combine concrete and symbolic execution for unit

testing

  • Why would you do this?
  • Concrete execution helps Symbolic execution to

simplify complex and unmanageable symbolic expressions

– By performing address resolution at run time – By replacing symbolic values by concrete values

127

slide-64
SLIDE 64

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

 Random Test Driver:

 random value for

x and y

 Probability of

reaching ERROR is extremely low

128

slide-65
SLIDE 65

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path condition

x = 22, y = 7 x = x0, y = y0

129

slide-66
SLIDE 66

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 22, y = 7, z = 14 x = x0, y = y0, z = 2*y0

130

slide-67
SLIDE 67

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 22, y = 7, z = 14 x = x0, y = y0, z = 2*y0 2*y0 != x0

131

slide-68
SLIDE 68

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition 2*y0 != x0

Solve: 2*y0 == x0 Solution: x0 = 2, y0 = 1

x = 22, y = 7, z = 14 x = x0, y = y0, z = 2*y0

132

slide-69
SLIDE 69

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 2, y = 1 x = x0, y = y0

133

slide-70
SLIDE 70

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 2, y = 1, z = 2 x = x0, y = y0, z = 2*y0

134

slide-71
SLIDE 71

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 2, y = 1, z = 2 x = x0, y = y0, z = 2*y0 2*y0 == x0

135

slide-72
SLIDE 72

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 2, y = 1, z = 2 x = x0, y = y0, z = 2*y0 2*y0 == x0 x0 > y0+10

136

slide-73
SLIDE 73

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 2, y = 1, z = 2 x = x0, y = y0, z = 2*y0 Solve: (2*y0 == x0) && (x0 > y0 + 10) Solution: x0 = 30, y0 = 15 2*y0 == x0 x0 > y0+10

137

slide-74
SLIDE 74

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 30, y = 15 x = x0, y = y0

138

slide-75
SLIDE 75

Concolic Testing Approach

int double (int v) { return 2*v; } void testme (int x, int y) { z = double (y); if (z == x) { if (x > y+10) { ERROR; } } }

Concrete Execution Symbolic Execution concrete state symbolic state path

condition x = 30, y = 15 x = x0, y = y0 2*y0 == x0 x0 > y0+10 Program Error

139

slide-76
SLIDE 76

Traverse all Paths

  • Traverse all

execution paths one by one to detect errors

– assertion violations – program crash – uncaught exceptions

  • combine with

valgrind to discover memory errors

F T F F F F T T T T T T

140

slide-77
SLIDE 77

Traverse all Paths

  • Traverse all

execution paths one by one to detect errors

– assertion violations – program crash – uncaught exceptions

  • combine with

valgrind to discover memory errors

F T F F F F T T T T T T

141

slide-78
SLIDE 78

Traverse all Paths

  • Traverse all

execution paths one by one to detect errors

– assertion violations – program crash – uncaught exceptions

  • combine with

valgrind to discover memory errors

F T F F F F T T T T T T

142

slide-79
SLIDE 79

Concolic Testing: A Middle Approach

+ Complex programs + Effjcient

  • Less coverage

+ No false positive

  • Simple programs
  • Not effjcient

+ High coverage

  • False positive

Random Testing Symbolic Testing Concolic Testing

+ Complex programs +/- Somewhat efficient + High coverage + No false positive

143

slide-80
SLIDE 80

144

Limitations: A Comparative View

Concolic: Broad, shallow Random: Narrow, deep

slide-81
SLIDE 81

Hybrid Concolic Testing

Interleave Random Testing and Concolic Testing to increase coverage Key idea: – Random testing leads to state s deep inside program – Concolic testing explores path starting in s and gives good local coverage Good for: Reactive programs (periodic input from environment) Not good for: Transformational programs

Reference Paper: Majumdar, Sen, Hybrid Concolic Testing http://srl.cs.berkeley.edu/~ksen/pubs/paper/hybrid.ps Aside: Motivated by similar idea used in VLSI design validation: Ganai et al. 1999, Ho et al. 2000

145

slide-82
SLIDE 82

146

Hybrid Concolic Testing

  • Interleave Random Testing and Concolic Testing to

increase coverage while (not required coverage) {

while (not saturation) perform random testing; Checkpoint; while (not increase in coverage) perform concolic testing; Restore; }

Deep, broad, hybrid Search

slide-83
SLIDE 83

Further reading

  • S. Anand et al. (2013) "An orchestrated survey of methodologies for

automated software test case generation," Journal of Systems and Software, 86:8, pp. 1978–2001. DOI: j.jss.2013.02.061 http://www.sciencedirect.com/science/article/pii/ S0164121213000563 See also: Zoltán MICSKEI’s page with a recent overview on tools: http://home.mit.bme.hu/~micskeiz/pages/ code_based_test_generation.html

83

slide-84
SLIDE 84

Acknowledgements

  • Some of the slides were adapted from

the lecture materials by Rupak Majumdar

147