Symstra: A Framework for Generating Object-Oriented Unit Tests - - PowerPoint PPT Presentation

symstra a framework for generating object oriented unit
SMART_READER_LITE
LIVE PREVIEW

Symstra: A Framework for Generating Object-Oriented Unit Tests - - PowerPoint PPT Presentation

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


slide-1
SLIDE 1

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

slide-2
SLIDE 2

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

  • f the invocation.

Automated test-input generation needs to produce:

Method sequences building relevant receiver object states Relevant method arguments

slide-3
SLIDE 3

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

  • f 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

slide-4
SLIDE 4

Outline

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

slide-5
SLIDE 5

Binary Search Tree Example

public 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 () { … } }

slide-6
SLIDE 6

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();

slide-7
SLIDE 7

Exploring Concrete States

Method arguments: insert(1), insert(2),

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

slide-8
SLIDE 8

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

slide-9
SLIDE 9

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 3

The second iteration

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

slide-10
SLIDE 10

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);

slide-11
SLIDE 11

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.

slide-12
SLIDE 12

Exploring Concrete States

new BST() insert(1)

2

insert(2)

3

insert(3)

1 1 2

insert(3) insert(2)

1 3

The second iteration

slide-13
SLIDE 13

State Abstraction: Symbolic States

new 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)

slide-14
SLIDE 14

State Abstraction: Symbolic States

new 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

slide-15
SLIDE 15

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

slide-16
SLIDE 16

Symbolic Execution Example

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++; }

slide-17
SLIDE 17

Exploring Symbolic States

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() S1

true

slide-18
SLIDE 18

Exploring Symbolic States

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

S2 insert(x1) S1

The first iteration

true true

slide-19
SLIDE 19

Exploring Symbolic States

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

S2 insert(x1) S1

The second iteration

true true x1 x1 < x2 x2

insert(x2) S3

slide-20
SLIDE 20

Exploring Symbolic States

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

S2 insert(x1) S1

The second iteration

true true x1 x1 < x2 x2

S3 insert(x2)

x1 x1 > x2 x2

S4

slide-21
SLIDE 21

Exploring Symbolic States

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

S2 insert(x1) S1

The second iteration

true true x1 x1 < x2 x2

S3 insert(x2)

x1 x1 > x2 x2

S4

x1 x1 = x2

S5

slide-22
SLIDE 22

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

S2 insert(x1) S1

The third iteration

true true x1 x1 < x2 x2

S3 insert(x2)

x1 x1 > x2 x2

S4

x1 x1 = x2

S5

?

slide-23
SLIDE 23

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

1

superset of

Symbolic states Concrete states

slide-24
SLIDE 24

Pruning Symbolic State

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

S2 insert(x1) S1

The third iteration

true true x1 x1 < x2 x2

S3 insert(x2)

x1 x1 > x2 x2

S4

x1 x1 = x2

S5

Pruned!

slide-25
SLIDE 25

new BST()

x1

S2 insert(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

slide-26
SLIDE 26

Evaluation

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

Concrete-State vs. Symstra

Focus on the key methods (e.g., add, remove)

  • f 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

slide-27
SLIDE 27

Statistics of Some Programs

84 111 63 8 84 59 19 84 537 42 7 83 28 8 83 185 12 6 TreeMap 100 9 1 8 100 8 0.8 7 100 7 0.6 100 9331 412 6 LinkedList 91 9 9 8 90 8 4 7 84 7 3 84 3036 51 6 BinomialHeap 100 1458 318 8 100 626 137 7 100 197 29 100 731 23 6 BinarySearchTree %cov #states Time (sec) %cov #states Time (sec) N class Symstra Concrete-State

Out of Memory Out of Memory Out of Memory Out of Memory

slide-28
SLIDE 28

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

1 2 3 4 5 6 7

slide-29
SLIDE 29

Related Work

Generating tests with concrete-state construction

e.g., TestEra [Marinov&Khurshid 01] and Korat [Boyapati et al. 02]

require specifications or repOK (class invariants)

Generating tests with symbolic execution

e.g. NASA Java Pathfinder [Khurshid et al. 03, Visser et al. 04]

require repOK (class invariants)

Directly construct new valid object states

slide-30
SLIDE 30

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

slide-31
SLIDE 31

Questions?