Automated Test Generation CS 6340. Outline Previously: Random testing (Fuzzing) – Security, mobile apps, concurrency Systematic testing: Korat – Linked.

Slides:



Advertisements
Similar presentations
Chapter 7. Binary Search Trees
Advertisements

Feedback-directed Random Test Generation (to appear in ICSE 2007) Carlos Pacheco Shuvendu Lahiri Michael Ernst Thomas Ball MIT Microsoft Research January.
Author: Carlos Pacheco, Shuvendu K. Lahiri, Michael D. Ernst, Thomas Ball MIT CSAIL.
Lists and the Collection Interface Chapter 4. Chapter Objectives To become familiar with the List interface To understand how to write an array-based.
Korat Automated Testing Based on Java Predicates Chandrasekhar Boyapati, Sarfraz Khurshid, Darko Marinov MIT ISSTA 2002 Rome, Italy.
Identity and Equality Based on material by Michael Ernst, University of Washington.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
1/20 Generalized Symbolic Execution for Model Checking and Testing Charngki PSWLAB Generalized Symbolic Execution for Model Checking and Testing.
Annoucements  Next labs 9 and 10 are paired for everyone. So don’t miss the lab.  There is a review session for the quiz on Monday, November 4, at 8:00.
Data Abstraction II SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
Feedback-Directed Random Test Generation Automatic Testing & Validation CSI5118 By Wan Bo.
1 CS2200 Software Development Lecture: Testing and Design A. O’Riordan, 2008 K. Brown,
1 Trees. 2 Outline –Tree Structures –Tree Node Level and Path Length –Binary Tree Definition –Binary Tree Nodes –Binary Search Trees.
CS 206 Introduction to Computer Science II 10 / 01 / 2008 Instructor: Michael Eckmann.
1 Today Another approach to “coverage” Cover “everything” – within a well-defined, feasible limit Bounded Exhaustive Testing.
CS 206 Introduction to Computer Science II 10 / 14 / 2009 Instructor: Michael Eckmann.
Loops – While, Do, For Repetition Statements Introduction to Arrays
Introduction to Computer Science Exam Information Unit 20.
OOP #10: Correctness Fritz Henglein. Wrap-up: Types A type is a collection of objects with common behavior (operations and properties). (Abstract) types.
1 Chapter 2 Introductory Programs. 2 Getting started To create and run a Java program –Create a text file with a.java extension for the source code. For.
1 Advanced Material The following slides contain advanced material and are optional.
AP Computer Science.  Not necessary but good programming practice in Java  When you override a super class method notation.
1/23/2003University of Virginia1 Korat: Automated Testing Based on Java Predicates CS751 Presentation by Radu Stoleru C.Boyapaty, S.Khurshid, D.Marinov.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 8: Semi-automated test generation via UDITA.
Korat: Automated Testing Based on Java Predicates Chandrasekhar Boyapati 1, Sarfraz Khurshid 2, and Darko Marinov 3 1 University of Michigan Ann Arbor.
Maps A map is an object that maps keys to values Each key can map to at most one value, and a map cannot contain duplicate keys KeyValue Map Examples Dictionaries:
CS2110 Recitation Week 8. Hashing Hashing: An implementation of a set. It provides O(1) expected time for set operations Set operations Make the set empty.
Software Testing Sudipto Ghosh CS 406 Fall 99 November 9, 1999.
Finding Errors in.NET with Feedback-Directed Random Testing Carlos Pacheco (MIT) Shuvendu Lahiri (Microsoft) Thomas Ball (Microsoft) July 22, 2008.
Feed Back Directed Random Test Generation Carlos Pacheco1, Shuvendu K. Lahiri2, Michael D. Ernst1, and Thomas Ball2 1MIT CSAIL, 2Microsoft Research Presented.
Korat: Automated Testing Based on Java Predicates
A Computer Science Tapestry 1 Recursion (Tapestry 10.1, 10.3) l Recursion is an indispensable technique in a programming language ä Allows many complex.
Bug Localization with Machine Learning Techniques Wujie Zheng
Chapter 1 Introduction to Computers and C++ Programming Goals: To introduce the fundamental hardware and software components of a computer system To introduce.
Data Structures Chapter 1- Introduction Mohamed Mustaq.A.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 6: Exhaustive Bounded Testing and Feedback-Directed Random Testing.
Chapter 25 Formal Methods Formal methods Specify program using math Develop program using math Prove program matches specification using.
Low-Level Detailed Design SAD (Soft Arch Design) Mid-level Detailed Design Low-Level Detailed Design Design Finalization Design Document.
Chapter 18 Java Collections Framework
Automated Patch Generation Adapted from Tevfik Bultan’s Lecture.
Feedback-directed Random Test Generation Carlos Pacheco Shuvendu Lahiri Michael Ernst Thomas Ball MIT Microsoft Research January 19, 2007.
Finding Errors in.NET with Feedback-Directed Random Testing Carlos Pacheco (MIT) Shuvendu Lahiri (Microsoft) Thomas Ball (Microsoft) July 22, 2008.
Directed Random Testing Evaluation. FDRT evaluation: high-level – Evaluate coverage and error-detection ability large, real, and stable libraries tot.
This recitation 1 An interesting point about A3: Using previous methods to avoid work in programming and debugging. How much time did you spend writing.
Testing Data Structures Tao Xie Visiting Professor, Peking University Associate Professor, North Carolina State University
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
Slides prepared by Rose Williams, Binghamton University Chapter 16 Collections and Iterators.
1 Chapter 6 Heapsort. 2 About this lecture Introduce Heap – Shape Property and Heap Property – Heap Operations Heapsort: Use Heap to Sort Fixing heap.
( = “unknown yet”) Our novel symbolic execution framework: - extends model checking to programs that have complex inputs with unbounded (very large) data.
CS527 Topics in Software Engineering (Software Testing and Analysis) Darko Marinov September 7, 2010.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved. Data Structures for Java William H. Ford William R. Topp Chapter 20 Ordered.
Random Test Generation of Unit Tests: Randoop Experience
Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution Tao Xie, Darko Marinov, Wolfram Schulte, and David Notkin University.
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 17 – Specifications, error checking & assert.
Testing Data Structures
Testing Tutorial 7.
CSE 374 Programming Concepts & Tools
CSPs: Search and Arc Consistency Computer Science cpsc322, Lecture 12
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Types of Testing Visit to more Learning Resources.
Dynamic Symbolic Data Structure Repair
Chapter 6 Intermediate-Code Generation
Coding Concepts (Basics)
50.530: Software Engineering
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
An Introduction to Programming though C++
slides created by Ethan Apter and Marty Stepp
Automated Test Generation
Presentation transcript:

Automated Test Generation CS 6340

Outline Previously: Random testing (Fuzzing) – Security, mobile apps, concurrency Systematic testing: Korat – Linked data structures Feedback-directed random testing: Randoop – Classes, libraries

Korat A test-generation research project Idea – Leverage pre-conditions and post-conditions to generate tests automatically But how?

The Problem There are infinitely many tests – Which finite subset should we choose? And even finite subsets can be huge Need a subset which is: – concise: Avoids illegal and redundant tests – diverse: Gives good coverage

An Insight Often can do a good job by systematically testing all inputs up to a small size Small Test Case Hypothesis: – If there is any test that causes the program to fail, there is a small such test If a list function works for lists of length 0 through 3, probably works for all lists – E.g., because the function is oblivious to the length

How Do We Generate Test Inputs? Use the types The class declaration shows what values (or null) can fill each field Simply enumerate all possible shapes with a fixed set of Nodes class BinaryTree { Node root; class Node { Node left; Node right; }

Scheme for Representing Shapes Order all possible values of each field Order all fields into a vector Each shape == vector of field values e.g.: BinaryTree of up to 3 Nodes: N0 N1 N2 root left right left right left right class BinaryTree { Node root; class Node { Node left; Node right; }

QUIZ: Representing Shapes Fill in the field values in each vector to represent the depicted shape: N0 N1 N2 root left right left right left right N2 N0 N1 N2 N0 N1

QUIZ: Representing Shapes Fill in the field values in each vector to represent the depicted shape: N0 N1N2null N0 N1null N2 null N0 N1 N2 root left right left right left right N2 N0 N1 N2 N0 N1

A Simple Algorithm User selects maximum input size k Generate all possible inputs up to size k Discard inputs where pre-condition is false Run program on remaining inputs Check results using post-condition

QUIZ: Enumerating Shapes What is the total number of vectors of the above form? Korat represents each input shape as a vector of the following form: N0 N1 N2 root left right left right left right

QUIZ: Enumerating Shapes What is the total number of vectors of the above form? Korat represents each input shape as a vector of the following form: N0 N1 N2 root left right left right left right 16384

The General Case for Binary Trees How many binary trees are there of size <= k? Calculation: – A BinaryTree object, bt – k Node objects, n0, n1, n2, … – 2k+1 Node pointers root (for bt ) left, right (for each Node object) – k+1 possible values ( n0, n1, n2, … or null ) per pointer (k+1)^(2k+1) possible “binary trees” class BinaryTree { Node root; class Node { Node left; Node right; }

A Lot of “Trees” ! The number of “trees” explodes rapidly – k = 3: over 16,000 “trees” – k = 4: over 1,900,000 “trees” – k = 5: over 360,000,000 “trees” Limits us to testing only very small input sizes Can we do better?

An Overestimate (k+1)^(2k+1) trees is a gross overestimate! Many of the shapes are not even trees: And many are isomorphic: N2N0N1 N2N0

How Many Trees? Only 9 distinct binary trees with at most 3 nodes

Another Insight Avoid generating inputs that don’t satisfy the pre-condition in the first place Use the pre-condition to guide the generation of tests

The Technique Instrument the pre-condition – Add code to observe its actions – Record fields accessed by the pre-condition Observation: – If the pre-condition doesn’t access a field, then pre-condition doesn’t depend on the field.

The Pre-Condition for Binary Trees Root may be null If root is not null: – No cycles – Each node (except root) has one parent – Root has no parent class BinaryTree { Node root; class Node { Node left; Node right; }

The Pre-Condition for Binary Trees N0 N1 N2 public boolean repOK(BinaryTree bt) { if (bt.root == null) return true; Set visited = new HashSet(); List workList = new LinkedList(); visited.add(bt.root); workList.add(bt.root); while (!workList.isEmpty()) { Node current = workList.removeFirst(); if (current.left != null) { if (!visited.add(current.left)) return false; workList.add(current.left); }... // similarly for current.right } return true; } class BinaryTree { Node root; class Node { Node left; Node right; }

Example: Using the Pre-Condition Consider the following “tree”: The pre-condition accesses only the root as it is null => Every possible shape for other nodes yields same result => This single input eliminates 25% of the tests! N2N0N1 null N1nullN2 null N0 N1 N2 root left right left right left right

Enumerating Tests Shapes are enumerated by their associated vectors – Initial candidate vector: all fields null – Next shape generated by: Expanding last field accessed in pre-condition Backtracking if all possibilities for a field are exhausted Key idea: Never expand parts of input not examined by pre-condition Also: Cleverly checks for and discards shapes isomorphic to previously-generated shapes

Example: Enumerating Binary Trees null 1 N0 null 123 N0 nullN0null N0 nullN1null N0 N1 N2 root left right left right left right

QUIZ: Enumerating Binary Trees What are the next two legal, non-isomorphic shapes Korat generates? N0 nullN1null N0 N1 N2 root left right left right left right

QUIZ: Enumerating Binary Trees What are the next two legal, non-isomorphic shapes Korat generates? N0 N1 N2 root left right left right left right N0 nullN1nullN2 null N0 nullN1N2null 67 N0 nullN1null 12345

QUIZ: Enumerating Binary Trees What are the next two legal, non-isomorphic shapes Korat generates? N0 N1 N2 root left right left right left right N0 nullN1N2null

QUIZ: Enumerating Binary Trees What are the next two legal, non-isomorphic shapes Korat generates? N0 N1null N0 N1N2null N0 N1 N2 root left right left right left right N0 nullN1N2null

Experimental Results

Strengths and Weaknesses Strong when we can enumerate all possibilities – e.g. Four nodes, two edges per node => Good for: Linked data structures Small, easily specified procedures Unit testing Weaker when enumeration is weak – Integers, Floating-point numbers, Strings

Weaknesses Only as good as the pre- and post-conditions Pre: is_member(x, list) List remove(Element x, List list) { if (x == head(list)) return tail(list); else return cons(head(list), remove(x, tail(list))); } Post: !is_member(x, list’)

Weaknesses Only as good as the pre- and post-conditions Pre: !is_empty(list) List remove(Element x, List list) { if (x == head(list)) return tail(list); else return cons(head(list), remove(x, tail(list))); } Post: is_list(list’)

Feedback-Directed Random Testing How do we generate a test like this? public static void test() { LinkedList l1 = new LinkedList(); Object o1 = new Object(); l1.addFirst(o1); TreeSet t1 = new TreeSet(l1); Set s1 = Collections.unmodifiableSet(t1); // This assertion fails assert(s1.equals(s1)); }

Overview Problem with uniform random testing: Creates too many illegal or redundant tests Idea: Randomly create new test guided by feedback from previously created tests test == method sequence Recipe: Build new sequences incrementally, extending past sequences As soon as a sequence is created, execute it Use execution results to guide test generation towards sequences that create new object states

Randoop: Input and Output Input: classes under test time limit set of contracts e.g. “o.hashCode() throws no exception” e.g. “o.equals(o) == true” Output: contract-violating test cases LinkedList l1 = new LinkedList(); Object o1 = new Object(); l1.addFirst(o1); TreeSet t1 = new TreeSet(l1); Set s1 = Collections.unmodifiableSet(t1); assert(s1.equals(s1)); No contract violated up to here fails when executed

Randoop Algorithm components = { int i = 0;, boolean b = false;... } // seed components Repeat until time limit expires: Create a new sequence – Randomly pick a method call T ret m(T1,...,Tn) – For each argument of type Ti, randomly pick sequence Si from components that constructs an object vi of that type – Create S new = S1;...; Sn; Tret vnew = m(v1...vn); Classify new sequence S new : discard / output as test / add to components

Classifying a Sequence execute sequence sequence illegal? Yes Discard sequence No contract violated? Yes Output sequence sequence redundant? Yes Discard sequence No Add to components No

Illegal Sequences Sequences that “crash” before contract is checked – E.g. throw an exception int i = -1; Date d = new Date(2006, 2, 14); d.setMonth(i); // pre: argument >= 0 assert(d.equals(d));

Redundant Sequences Maintain set of all objects created in execution of each sequence New sequence is redundant if each object created during its execution belongs to above set (using equals to compare) Could also use more sophisticated state equivalence methods Set s = new HashSet(); s.add(“hi”); s.isEmpty(); assertTrue(s.equals(s)); Set s = new HashSet(); s.add(“hi”); assertTrue(s.equals(s));

Some Errors Found by Randoop JDK containers have 4 methods that violate o.equals(o) contract Javax.xml creates objects that cause hashCode and toString to crash, even though objects are well-formed XML constructs Apache libraries have constructors that leave fields unset, leading to NPE on calls of equals, hashCode, and toString.Net framework has at least 175 methods that throw an exception forbidden by the library specification (NPE, out-of-bounds, or illegal state exception).Net framework has 8 methods that violate o.equals(o) contract

QUIZ: Randoop Test Generation (Part 1) class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } } Write the smallest sequence that Randoop can possibly generate to create a valid BinaryTree. Once generated, how does Randoop classify it? Discards it as illegal Outputs it as a bug Adds to components for future extension

QUIZ: Randoop Test Generation (Part 1) Write the smallest sequence that Randoop can possibly generate to create a valid BinaryTree. Once generated, how does Randoop classify it? Discards it as illegal Outputs it as a bug Adds to components for future extension BinaryTree bt = new BinaryTree(null); class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } }

QUIZ: Randoop Test Generation (Part 2) class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } } Write the smallest sequence that Randoop can possibly generate that violates the assertion in removeRoot(). Once generated, how does Randoop classify it? Discards it as illegal Outputs it as a bug Adds to components for future extension

QUIZ: Randoop Test Generation (Part 2) Write the smallest sequence that Randoop can possibly generate that violates the assertion in removeRoot(). Once generated, how does Randoop classify it? Discards it as illegal Outputs it as a bug Adds to components for future extension BinaryTree bt = new BinaryTree(null); bt.removeRoot(); class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } }

QUIZ: Randoop Test Generation (Part 3) class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } Write the smallest sequence that Randoop can possibly generate that violates the assertion in BinaryTree’s constructor. Can Randoop create a BinaryTree object with cycles using the given API? Yes No class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } }

QUIZ: Randoop Test Generation (Part 3) Node v1 = new Node(null, null); Node v2 = new Node(v1, v1); BinaryTree bt = new BinaryTree(v2); v2 v1 class BinaryTree { Node root; public BinaryTree(Node r) { root = r; assert(repOk(this)); } public Node removeRoot() { assert(root != null);... } } class Node { Node left; Node right; public Node(Node l, Node r) { left = l; right = r; } } Write the smallest sequence that Randoop can possibly generate that violates the assertion in BinaryTree’s constructor. Can Randoop create a BinaryTree object with cycles using the given API? Yes No

QUIZ: Korat and Randoop Identify which statements are true for each test generation technique: KoratRandoop Uses type information to guide test generation. Each test is generated fully independently of past tests. Generates tests deterministically. Suited to test method sequences. Avoids generating redundant tests.

QUIZ: Korat and Randoop Identify which statements are true for each test generation technique: KoratRandoop Uses type information to guide test generation. Each test is generated fully independently of past tests. Generates tests deterministically. Suited to test method sequences. Avoids generating redundant tests.

Test Generation: The Bigger Picture Why didn’t automatic test generation become popular decades ago? Belief: Weak-type systems – Test generation relies heavily on type information – C, Lisp just didn’t provide the needed types Contemporary languages lend themselves better to test generation – Java, UML

What Have We Learned? Automatic test generation is a good idea – Key: avoid generating illegal and redundant tests Even better, it is possible to do – At least for unit tests in strongly-typed languages Being adopted in industry – Likely to become widespread