symstra a framework for generating object oriented unit
play

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


  1. 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 Microsoft Research

  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 of the invocation. � Automated test-input generation needs to produce: � Method sequences building relevant receiver object states � Relevant method arguments

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

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

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

  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] Test 1: Test 2: BST t1 = new BST(); BST t2 = new BST(); t1.size(); t2.size(); t2.size(); � 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)

  7. Exploring Concrete States � Method arguments: insert(1), insert(2), insert(3), remove(1), remove(2), remove(3) new BST()

  8. Exploring Concrete States � Method arguments: insert(1), insert(2), insert(3), remove(1), remove(2), remove(3) new BST() remove(1) remove(2) remove(3) insert(1) insert(2) insert(3) 1 2 3 The first iteration

  9. Exploring Concrete States � Method arguments: insert(1), insert(2), insert(3), remove(1), remove(2), remove(3) new BST() remove(1) remove(1) remove(2) remove(3) insert(1) insert(2) insert(3) remove(2) remove(3) insert(1) 1 2 3 insert(2) insert(3) … 1 1 2 3 The second iteration

  10. Generating Tests from Exploration � Collect method sequence along the shortest path (constructor-call edge � each method-call edge) new BST() remove(1) remove(1) remove(2) remove(3) insert(1) insert(2) insert(3) remove(2) remove(3) insert(1) 1 2 3 insert(3) insert(2) … BST t = new BST(); t.insert(1); 1 1 t.insert(3); 2 3

  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.

  12. Exploring Concrete States new BST() insert(3) insert(1) insert(2) 1 2 3 … insert(2) insert(3) 1 1 2 3 The second iteration

  13. State Abstraction: Symbolic States new BST() new BST() insert(x 1 ) insert(3) insert(1) insert(2) x1 1 2 3 … insert(2) insert(3) 1 1 2 3 The second iteration

  14. State Abstraction: Symbolic States new BST() new BST() insert(x 1 ) insert(3) insert(1) insert(2) x1 1 2 3 … insert(x 2 ) insert(2) insert(3) x 1 < x 2 1 1 x1 2 3 x2 The second iteration

  15. Symbolic Execution � Execute a method on symbolic input values � inputs: insert(SymbolicInt x) if (P) � Explore paths of the method PC: P ...; if (Q) PC: P && Q ...; � Build a path condition for each path � conjunct conditionals or their negations � Produce symbolic states (<heap, path condition>) x 1 < x 2 � e.g., x1 x2

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

  17. Exploring Symbolic States new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true 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++; }

  18. Exploring Symbolic States new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... } else return; } } size++; } The first iteration

  19. Exploring Symbolic States new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... insert(x 2 ) } else return; } S 3 } size++; x 1 < x 2 } x 1 The second iteration x 2

  20. Exploring Symbolic States new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... insert(x 2 ) } else return; } S 3 S 4 } size++; x 1 < x 2 x 1 > x 2 } x 1 x 1 The second iteration x 2 x 2

  21. Exploring Symbolic States new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... insert(x 2 ) } else return; } S 3 S 4 S 5 } size++; x 1 < x 2 x 1 > x 2 x 1 = x 2 } x 1 x 1 x 1 The second iteration x 2 x 2

  22. Which States to Explore Next? new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... insert(x 2 ) } else return; } S 3 S 4 S 5 } size++; x 1 < x 2 x 1 > x 2 x 1 = x 2 } x 1 x 1 x 1 ? The third iteration x 2 x 2

  23. Symbolic State Subsumption � Symbolic state S 2 : <H 2 ,c 2 > subsumes S 5 : <H 5 ,c 5 > � Heaps H 2 and H 5 are isomorphic � Path condition c 5 → c 2 [CVC Lite, Omega] � Concrete states represented by S 2 are a superset of concrete states represented by S 5 � If S 2 has been explored, S 5 is pruned. � Still guarantee path coverage within a method (x1 = x2) → true S 2 S 5 x 1 = x 2 true Symbolic subsumes states x 1 x 1 Concrete superset of 1 2 3 1 2 3 states … …

  24. Pruning Symbolic State new BST() S 1 public void insert(SymbolicInt x) { if (root == null) { true root = new Node(x); } else { Node t = root; while (true) { insert(x 1 ) if (t.value < x) { S 2 //explore the right subtree true ... x 1 } else if (t.value > x) { //explore the left subtree ... insert(x 2 ) } else return; } S 3 S 4 S 5 } size++; x 1 < x 2 x 1 > x 2 x 1 = x 2 } x 1 x 1 x 1 The third iteration Pruned! x 2 x 2

  25. Generating Tests from Exploration new BST() S 1 � Collect method sequence along the true shortest path (constructor-call edge � each method-call edge) insert(x 1 ) � Generate concrete arguments by S 2 using a constraint solver [POOC] true x 1 BST t = new BST(); insert(x 2 ) t.insert(x 1 ); t.insert(x 2 ); S 3 S 4 S 5 x 1 < x 2 x 1 < x 2 x 1 > x 2 x 1 = x 2 BST t = new BST(); t.insert(-1000000); x 1 x 1 x 1 t.insert(-999999); x 2 x 2

  26. 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

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

  28. Code Coverage and (Seeded-)Bug Coverage with Iterations (Binary Search Tree) 100% 90% 80% 70% 60% CodeCov 50% BugCov 40% 30% 20% 10% 0% 0 1 2 3 4 5 6 7 i0 i1 i2 i3 i4 i5 i6 i7 Iteration

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend