Rigorous Software Development CSCI-GA 3033-011 Instructor: Thomas Wies Spring 2012 Lecture 7.

Slides:



Advertisements
Similar presentations
Chapter 22 Implementing lists: linked implementations.
Advertisements

Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and.
Advanced programming tools at Microsoft
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Design By Contract Using JMSAssert.
Lists and the Collection Interface Chapter 4. Chapter Objectives To become familiar with the List interface To understand how to write an array-based.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 10.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 6 Disclaimer. These notes are derived from notes originally.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 8.
Practice Session 5 Java: Packages Collection Classes Iterators Generics Design by Contract Test Driven Development JUnit.
1 Unit Testing with JUnit CS 3331 Fall 2009 Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report, 3(7):37-50, Available.
Korat Automated Testing Based on Java Predicates Chandrasekhar Boyapati, Sarfraz Khurshid, Darko Marinov MIT ISSTA 2002 Rome, Italy.
Semantics Static semantics Dynamic semantics attribute grammars
A System to Generate Test Data and Symbolically Execute Programs Lori A. Clarke September 1976.
Chapter 1 Writing a Program Fall Class Overview Course Information –On the web page and Blackboard –
J-Unit Framework.
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.
Data Abstraction II SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
JMLAutoTest and Its Double- phase Testing Way Guoqing Xu Com Sci., East China Normal Univ. Shanghai , PRC FATES 2003, Montreal, Canada, Oct.6th 2003.
T ESTING WITH J UNIT IN E CLIPSE Farzana Rahman. I NTRODUCTION The class that you will want to test is created first so that Eclipse will be able to find.
Lecture 8 CS203. Implementation of Data Structures 2 In the last couple of weeks, we have covered various data structures that are implemented in the.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION TESTING II Autumn 2011.
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.
Writing a Unit test Using JUnit At the top of the file include: import junit.framework.TestCase; The main class of the file must be: public Must extend.
Feb. 23, 2004CS WPI1 CS 509 Design of Software Systems Lecture #5 Monday, Feb. 23, 2004.
Presentation Outline What is JUnit? Why Use JUnit? JUnit Features Design of JUnit Downloading JUnit Writing Tests – TestCase – TestSuite Organizing The.
1/23/2003University of Virginia1 Korat: Automated Testing Based on Java Predicates CS751 Presentation by Radu Stoleru C.Boyapaty, S.Khurshid, D.Marinov.
Korat: Automated Testing Based on Java Predicates Chandrasekhar Boyapati 1, Sarfraz Khurshid 2, and Darko Marinov 3 1 University of Michigan Ann Arbor.
Subclasses and Subtypes CMPS Subclasses and Subtypes A class is a subclass if it has been built using inheritance. ▫ It says nothing about the meaning.
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:
Ranga Rodrigo. Class is central to object oriented programming.
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
Language Evaluation Criteria
(c) University of Washingtonhashing-1 CSC 143 Java Hashing Set Implementation via Hashing.
Data Structures Using C++ 2E Chapter 6 Recursion.
JUnit The framework. Goal of the presentation showing the design and construction of JUnit, a piece of software with proven value.
A Safety-Critical Java Technology Compatibility Kit Hans Søndergaard Stephan Korsholm VIA University College, Horsens, Denmark & Anders P. Ravn Aalborg.
Data Structures Using C++ 2E Chapter 6 Recursion.
(c) University of Washington14-1 CSC 143 Java Collections.
1 Assertions. 2 assertions communicate assumptions about the state of the program, and stop processing if they turn out to be false very often comments.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 6: Exhaustive Bounded Testing and Feedback-Directed Random Testing.
A Novel Approach to Unit Test: The Aspect-Oriented Way Guoqing Xu and Zongyuan Yang Software Engineering Lab (SEL) East China Normal University
CS 363 Comparative Programming Languages Semantics.
Code Contracts Parameterized Unit Tests Tao Xie. Example Unit Test Case = ? Outputs Expected Outputs Program + Test inputs Test Oracles 2 void addTest()
Data structures Abstract data types Java classes for Data structures and ADTs.
Introduction to JUnit 3.8 SEG 3203 Winter ‘07 Prepared By Samia Niamatullah.
CSC 213 – Large Scale Programming Lecture 15: Heap-based Priority Queue.
(c) University of Washington15-1 CSC 143 Java List Implementation via Arrays Reading: 13.
1 CSCD 326 Data Structures I Software Design. 2 The Software Life Cycle 1. Specification 2. Design 3. Risk Analysis 4. Verification 5. Coding 6. Testing.
90-723: Data Structures and Algorithms for Information Processing Copyright © 1999, Carnegie Mellon. All Rights Reserved. 1 Lecture 1: Introduction Data.
JUnit A framework which provides hooks for easy testing of your Java code, as it's built Note: The examples from these slides can be found in ~kschmidt/public_html/CS265/Labs/Java/Junit.
Automated Test Generation CS Outline Previously: Random testing (Fuzzing) – Security, mobile apps, concurrency Systematic testing: Korat – Linked.
Iteration Abstraction SWE Software Construction Fall 2009.
Unit Testing. F-22 Raptor Fighter Manufactured by Lockheed Martin & Boeing How many parts does the F-22 have?
JAVA: An Introduction to Problem Solving & Programming, 6 th Ed. By Walter Savitch ISBN © 2012 Pearson Education, Inc., Upper Saddle River,
Unit Testing with FlexUnit
Object Design More Design Patterns Object Constraint Language Object Design Specifying Interfaces Review Exam 2 CEN 4010 Class 18 – 11/03.
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.
Reasoning and Design (and Assertions). How to Design Your Code The hard way: Just start coding. When something doesn’t work, code some more! The easier.
Rigorous Software Development CSCI-GA
Accessible Formal Methods A Study of the Java Modeling Language
Introduction to Data Structures
Hoare-style program verification
Data Structures and Algorithms for Information Processing
Test Driven Development
Test Driven Development
Java Modeling Language (JML)
Presentation transcript:

Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 7

Programming Project: Minesweeper

Project Goal Implement a minesweeper game together with a perfect minesweeper solver – perfect solver: never guess the next move unless the current board configuration does not allow to deduce whether some unrevealed cell contains a mine or not. – in particular: a perfect solver can decide whether a given board configuration can be solved without guessing.

Project Outline Phase 1: Alloy Model Phase 2: Java Implementation

Project Phase 1: Alloy model Objectives: – develop abstract minesweeper model – simulate board configurations and plays of the game – specify key invariants of board configurations – identify pre and post-conditions of operations on boards – implement simple minesweeper solver Deadline: Tuesday, April 10, 2012

Project Phase 2: Java Implementation Objectives: – Transfer Alloy model to JML specifications – Implement simple parser for board configurations game solver – Check JML specifications using JML tools Deadline: Tuesday, May 1, 2012 Competition: – submitted solvers will compete against each other

Alloy Model Abstract Minesweeper: game is played on an undirected graph rather than a grid-like board – nodes represent cells of the board – edges indicate which cells are neighbors 2

Invariants of Board Configurations Marked cells are not revealed. The number of marked cells is not larger than the number of mines. If x is a revealed cell that has no neighboring mines, then all its neighbors are also revealed....

Solving Minesweeper Games Solving minesweeper games is closely related to the Minesweeper Consistency Problem: – given a board configuration – does there exist an assignment of mines to unrevealed cells that is consistent with the conf.?

Minesweeper Consistency: Example Is this configuration consistent? No!

Minesweeper Consistency: Example and this one? Yes!

Minesweeper Consistency The Minesweeper Consistency Problem is NP-complete. There is a simple brute-force algorithm to solve minesweeper games. If you want a solver that works fast in practice, you will have to do something more clever.

Programming Project Phase 1: Alloy Model – Deadline: Tuesday, April 10, 2012 Phase 2: Java Implementation – Deadline: Tuesday, May 1, 2012 More detailed information will be available on the course webpage.

Todays Topic: Automated Test Case Generation

How to Test Effectively? public class Factorial { requires n >= ensures \result > public static int factorial (int n) { int result = n; while (--n > 0) result *= n; return result; } public static void main (String[] param) { int n = Integer.parseInt(param[0]); int fact_n = factorial(n); System.out.println("n: " + n + ", n!: " + fact_n); } Writing a main method for each test case does not scale.

public void enqueue(Comparable o) { if (numElems >= elems.length) grow(); int pos = numElems++; int parent = pos / 2; while (pos > 0 && elems[parent].compareTo(o) > 0) { elems[pos] = elems[parent]; pos = parent; parent = pos / 2; } elems[pos] = o; } How to Test Effectively? Faulty implementation of enqueue on binary heap: Writing all test cases manually does not scale.

Automated Testing Unit Testing: write code to automatically test your code. A unit test is a test suite for a unit (class/module) of a program and consists of – setup code to initialize the tested class; – tear down code to clean up after testing; – test cases that call methods of the tested class with appropriate inputs and then check the results. Once test suites are written, they are easy to run repeatedly (regression testing).

Unit Testing in Java: JUnit A popular framework for unit testing in Java – Frameworks are libraries with gaps – Programmer writes classes following particular conventions to fill in the gaps – Result is the complete product JUnit automates – the execution and analysis of unit tests; – generation of tests cases from parameterized test oracles and user-provided test data.

JUnit Example import static org.junit.Assert.*; import org.junit.*;... public class PriorityQueueTest { private PriorityQueue public void setUp () { pq = new Heap(); public void tearDown () { pa = null; public void enqueueTest () { Integer value = new Integer(5); pq.enqueue(value); assertEquals(pq.removeFirst, value); }... }

Drawbacks of JUnit Low degree of automation – Programmer still needs to write all the test cases Redundant specification – Duplication between checks in test oracles and formal specification (e.g. provided as JML annotations)

JMLUnit is a unit testing framework for JML built on top of JUnit User: writes specifications supplies test data of each type JMLUnit automatically: constructs test cases from test data assembles test cases into test suites executes test suites decides success or failure reports results JMLUnit: Unit Testing for JML

Test Cases and Suites A test case (o,x) consists of: – a non-null receiver object o – a sequence x of argument objects A test suite for method m is a set of test cases with: – receiver of m s receiver type – arguments of m s argument types

Test Suites are Cross Products For method enqueue : { (pq, v) | pq PriorityQueueTestData, v IntegerTestData } Default is to use all data for all methods – Filtered automatically by preconditions – Users can filter manually if desired Factory method allows user control of adding test cases to test suite.

Errors and Meaningless Test Cases When testing method m : check m s postcondition receiver.m(arg1,...) check m s precondition {... } check f s precondition {... x.f(...); } check f s postcondition entry precondition violation internal precondition violation other violation Entry precondition violation ) test case rejected Internal or other violation ) error reported

Supplying Test Data Programmer supplies data in form of strategies A strategy for type T : – has method that returns iterator yielding T Strategies allow reuse of test data JMLUnit provides framework of built-in strategies – Strategies for built-in types – Allow for easy extension, composition, filtering, etc.

Strategies for Test Data Standard strategies: – Immutable: iterate over array of values; – Cloneable: iterate over array, clone each; – Other: create objects each time. Cloning and creating from scratch can prevent unwanted interference between tests. JMLUnit tries to guess appropriate strategy.

Example Strategies import org.jmlspecs.jmlunit.strategies.*; import junit.framework.*; public abstract class Heap_JML_TestData extends TestCase { public IntIterator vCompIter(String methodName, int argNum) { return vComparableStrategy.ComparableIterator(); } private StrategyType vComparableStrategy = new ImmutableObjectAbstractStrategy() { protected Object[] addData() { return new Integer[] {10, -22, 55, 3000}; } };...

Example Strategies... public IndefiniteIterator vHeapIter (String methodName, int argNum) { return vPointStrategy.iterator(); } private StrategyType vHeapStrategy = new NewObjectAbstractStrategy() { protected Object make(int n) { switch (n) { case 0: return new Heap(); case 1: return new Heap(new Integer {1, 2, 3}); default: break; } throw new NoSuchElementException(); } }; }

Using JMLUnit JML-compile the class to be tested jmlc Factorial.java generate the test suite and test data templates jmlunit Factorial.java supply the test data $EDITOR Factorial_JML_TestData.java compile the test suite export CLASSPATH=.:$JMLDIR/bin/jmlruntime.jar:$JMLDIR/specs javac Factorial_JML_Test*.java execute the test suite jmlrac Factorial_JML_Test

Drawbacks of JMLUnit High memory consumption: – JUnit test suite with all test cases is constructed in memory before it is executed. Limited degree of automation: – only test data for primitive types is generated automatically Limited degree of granularity: – fine-grained filtering of test data for individual methods is difficult

Alternatives to JMLUnit JMLUnitNG – similar feature set as JMLUnit – lazy generation of test suites and lazy result aggregation (better memory footprint) – improved filtering of test data – not based on JUnit Korat, TestEra, UDITA – automated generation of test data for complex data types

Automated Test Case Generation with Korat Provides test case generation for complex data types. Supports checking of JML specifications. User provides for each complex data type – a Java predicate capturing the representation invariant of the data type; – a finitization of the data type. Korat generates test cases for all instances that satisfy both the finitization constraints and the representation predicate.

Example: Binary Trees import java.util.*; class BinaryTree { private Node root; private int size; static class Node { private Node left; private Node right; }... }

Representation Predicate for BinaryTree public boolean repOK() { if (root == null) return size == 0; Set visited = new HashSet(); visited.add(root); LinkedList workList = new LinkedList(); workList.add(root); while (!workList.isEmpty()) { Node current = (Node) workList.removeFirst(); if (current.left != null) { if (!visited.add(current.left)) return false; worklist.add(current.left); } if (current.right!= null) {... } } return visited.size () == size; }

Finitization for BinaryTree public static Finitization finBinaryTree (int NUM_Node) { IFinitization f = new Finitization(BinaryTree.class); IObjSet nodes = f.createObjSet(Node.class, NUM_Node, true); // #Node = NUM_Node f.set(root, nodes); // root in null + Node IIntSet sizes = f.createIntSet(Num_Node); f.set(size, sizes); // size = NUM_Node f.set(Node.left, nodes); // Node.left in null + Node f.set(Node.right, nodes); // Node.right in null + Node return f; }

Finitization for BinaryTree Instances generated for finBinaryTree(3) right left right left right left