Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution

31
Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution Tao Xie, Darko Marinov, Wolfram Schulte, and David Notkin University of Washington University of Illinois at Urbana-Champaign Microsoft Research 1 2 3 1 1 2 3

description

Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution. Tao Xie, Darko Marinov, Wolfram Schulte, and David Notkin . 1. 3. 1. 2. 1. University of Washington University of Illinois at Urbana-Champaign Microsoft Research. 2. 3. Motivations. - PowerPoint PPT Presentation

Transcript of Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution

Page 1: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Symstra: A Framework for Generating Object-Oriented Unit Tests

using Symbolic Execution

Tao Xie, Darko Marinov, Wolfram Schulte, and David Notkin

University of WashingtonUniversity of Illinois at Urbana-Champaign

Microsoft Research

1 2 3 1

1

2

3

Page 2: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Motivations Object-oriented unit tests consist of sequences of method

invocations.

Behavior of an invocation depends on the method’s arguments and the state of the receiver at the beginning of the invocation.

Automated test-input generation needs to produce: Method sequences building relevant receiver object states Relevant method arguments

Page 3: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Motivations Object-oriented unit tests consist of sequences of method

invocations.

Behavior of an invocation depends on the method’s arguments and the state of the receiver at the beginning of the invocation.

Automated test-input generation needs to produce: Method sequences building relevant receiver object states Relevant method arguments

Symstra achieves both tasks using symbolic execution of method sequences with symbolic arguments

Page 4: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Outline Motivations Example Test generation by exploring concrete states Symstra: exploring symbolic states Evaluation Conclusion

Page 5: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Binary Search Tree Examplepublic class BST implements Set { Node root; int size; static class Node { int value; Node left; Node right;

} public void insert (int value) { … } public void remove (int value) { … } public bool contains (int value) { … } public int size () { … }}

Page 6: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Previous Test-Generation Approaches Straightforward approach: generate all (bounded)

possible sequences of calls to the methods under test too many and many are redundant [Xie et al. 04]

Concrete-state exploration approach [Willem et al. 04, Xie et al. 04] assume a given set of method call arguments explore new receiver-object states with method calls

(in breadth-first manner)

Test 1: BST t1 = new BST();t1.size();

Test 2: BST t2 = new BST();t2.size();t2.size();

Page 7: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Concrete States Method arguments: insert(1), insert(2),

insert(3), remove(1), remove(2), remove(3)

new BST()

Page 8: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Concrete States Method arguments: insert(1), insert(2),

insert(3), remove(1), remove(2), remove(3)

new BST()

insert(1)

2

insert(2)

remove(2)remove(1)

3

insert(3)

remove(3)

1

The first iteration

Page 9: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Concrete States Method arguments: insert(1), insert(2),

insert(3), remove(1), remove(2), remove(3)

new BST()

insert(1)

2

insert(2)

remove(2)remove(1)

3

insert(3)

remove(3)

1

1

2

insert(3)

1

3The second iteration

insert(2)

insert(1)remove(3)remove(2)

remove(1)

Page 10: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Generating Tests from Exploration Collect method sequence along the shortest path

(constructor-call edge each method-call edge)new BST()

insert(1)

2

insert(2)

remove(2)remove(1)

3

insert(3)

remove(3)

1

1

2

insert(3)

1

3

insert(2)

insert(1)remove(3)remove(2)

remove(1)

…BST t = new BST();t.insert(1);t.insert(3);

Page 11: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Issues of Concrete-State Exploration

State explosion (still) need at least N different insert arguments to

reach a BST with size N run out of memory when N reaches 7

Relevant-argument determination assume a set of given relevant arguments

e.g., insert(1), insert(2), insert(3), etc.

Page 12: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Concrete Statesnew BST()

insert(1)

2

insert(2)

3

insert(3)

1

1

2

insert(3)insert(2)

1

3

The second iteration

Page 13: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

State Abstraction: Symbolic Statesnew BST()

insert(1)

2

insert(2)

3

insert(3)

1

1

2

x1

insert(x1)

1

3

new BST()

The second iteration

…insert(3)insert(2)

Page 14: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

State Abstraction: Symbolic Statesnew BST()

insert(1)

2

insert(2)

3

insert(3)

1

1

2

insert(3)insert(2)

x1

x1

x2

x1 < x2

insert(x1)

insert(x2)

1

3

new BST()

The second iteration

Page 15: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Symbolic Execution Execute a method on symbolic input values

inputs: insert(SymbolicInt x)

Explore paths of the method

Build a path condition for each path conjunct conditionals or their negations

Produce symbolic states (<heap, path condition>) e.g.,

if (P) ...;

if (Q) ...;

PC: P

PC: P && Q

x1

x2

x1 < x2

Page 16: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Symbolic Execution Examplepublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

Page 17: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Symbolic Statespublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()S1

true

Page 18: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Symbolic Statespublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The first iteration

true

true

Page 19: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Symbolic Statespublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The second iteration

true

true

x1

x1 < x2

x2

insert(x2)

S3

Page 20: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Symbolic Statespublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The second iteration

true

true

x1

x1 < x2

x2

S3

insert(x2)

x1

x1 > x2

x2

S4

Page 21: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Exploring Symbolic Statespublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The second iteration

true

true

x1

x1 < x2

x2

S3

insert(x2)

x1

x1 > x2

x2

S4

x1

x1 = x2

S5

Page 22: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Which States to Explore Next?public void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The third iteration

true

true

x1

x1 < x2

x2

S3

insert(x2)

x1

x1 > x2

x2

S4

x1

x1 = x2

S5

?

Page 23: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Symbolic State Subsumption Symbolic state S2:<H2,c2> subsumes S5:<H5,c5>

Heaps H2 and H5 are isomorphic Path condition c5 c2 [CVC Lite, Omega]

Concrete states represented by S2 are a superset of concrete states represented by S5

If S2 has been explored, S5 is pruned. Still guarantee path coverage within a method

x1

true

S5

x1

x1 = x2

S2

subsumes

(x1 = x2) true

1 2 3

…2 3

…1superset of

Symbolic states

Concrete states

Page 24: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Pruning Symbolic Statepublic void insert(SymbolicInt x) { if (root == null) { root = new Node(x); } else { Node t = root; while (true) { if (t.value < x) { //explore the right subtree ...

} else if (t.value > x) { //explore the left subtree ... } else return; } } size++;}

new BST()

x1

S2insert(x1)

S1

The third iteration

true

true

x1

x1 < x2

x2

S3

insert(x2)

x1

x1 > x2

x2

S4

x1

x1 = x2

S5

Pruned!

Page 25: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

new BST()

x1

S2insert(x1)

S1

true

true

x1

x1 < x2

x2

S3

insert(x2)

x1

x1 > x2

x2

S4

x1

x1 = x2

S5

Collect method sequence along the shortest path (constructor-call edge each method-call edge)

Generate concrete arguments by using a constraint solver [POOC]

BST t = new BST();t.insert(x1);t.insert(x2);

x1 < x2

BST t = new BST();t.insert(-1000000);t.insert(-999999);

Generating Tests from Exploration

Page 26: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Evaluation Generate tests up to N (1..8) iterations

Concrete-State vs. Symstra Focus on the key methods (e.g., add, remove)

of seven Java classes from various sources most are complex data structures

Measure #states, time, and code coverage Pentium IV 2.8 GHz, Java 2 JVM with 512 MB Experimental results show Symstra effectively

reduces the state space for exploration reduces the time for achieving code coverage

Page 27: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Statistics of Some Programsclass N

Concrete-State SymstraTime(sec)

#states %cov Time (sec)

#states %cov

BinarySearchTree 6 23 731 100 29 197 1007 137 626 1008 318 1458 100

BinomialHeap 6 51 3036 84 3 7 847 4 8 908 9 9 91

LinkedList 6 412 9331 100 0.6 7 1007 0.8 8 1008 1 9 100

TreeMap 6 12 185 83 8 28 837 42 537 84 19 59 848 63 111 84

Out of Memory

Out of Memory

Out of Memory

Out of Memory

Page 28: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Code Coverage and (Seeded-)Bug Coverage with Iterations (Binary Search Tree)

0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

100%

i0 i1 i2 i3 i4 i5 i6 i7

Iteration

CodeCov

BugCov

0 1 2 3 4 5 6 7

Page 29: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Related Work

Generating tests with concrete-state constructione.g., TestEra [Marinov&Khurshid 01] and Korat [Boyapati et al. 02]

require specifications or repOK (class invariants)

Generating tests with symbolic executione.g. NASA Java Pathfinder [Khurshid et al. 03, Visser et al. 04]

require repOK (class invariants)

Directly construct new valid object states

Page 30: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Conclusion Automated test-input generation needs to

produce: method sequences building relevant receiver object

states relevant method arguments

Symstra exhaustively explores method sequences with symbolic arguments prune exploration based on state subsumption generate concrete arguments using a constraint solver

The experimental results show Symstra’s effectiveness over the existing concrete-state exploration approaches

Page 31: Symstra: A Framework for  Generating Object-Oriented Unit Tests  using Symbolic Execution

Questions?