DEBUGGING AND TESTING WITH SCALACHECK. Martina Seidl 2017/11/14

Similar documents
Debugging and Testing with ScalaCheck

Deductive Verification

A Short Introduction to Hoare Logic

Reasoning About Imperative Programs. COS 441 Slides 10b

Simply Typed Lambda Calculus

EDA045F: Program Analysis LECTURE 10: TYPES 1. Christoph Reichenbach

1 Trees. Listing 1: Node with two child reference. public class ptwochildnode { protected Object data ; protected ptwochildnode l e f t, r i g h t ;

Program Analysis Part I : Sequential Programs

Synthesis of Fast Programs for Maximum Segment Sum Problems

CSE 331 Software Design & Implementation

Floyd-Hoare Style Program Verification

TDDD08 Tutorial 1. Who? From? When? 6 september Victor Lagerkvist (& Wªodek Drabent)

COP4020 Programming Languages. Introduction to Axiomatic Semantics Prof. Robert van Engelen

Clojure Concurrency Constructs, Part Two. CSCI 5828: Foundations of Software Engineering Lecture 13 10/07/2014

Recitation 4: Eventful Tactical KeYmaera X Proofs /15-624/ Logical Foundations of Cyber-Physical Systems

Axiomatic semantics. Semantics and Application to Program Verification. Antoine Miné. École normale supérieure, Paris year

Using the Prover I: Lee Pike. June 3, NASA Langley Formal Methods Group Using the Prover I:

CS558 Programming Languages

Axiomatic Semantics: Verification Conditions. Review of Soundness and Completeness of Axiomatic Semantics. Announcements

Hoare Logic: Reasoning About Imperative Programs

Introduction to lambda calculus Part 6

INTRODUCTION. This is not a full c-programming course. It is not even a full 'Java to c' programming course.

Distributed Systems Byzantine Agreement

CMSC 132, Object-Oriented Programming II Summer Lecture 10:

Software Testing Lecture 7 Property Based Testing. Justin Pearson

CS5371 Theory of Computation. Lecture 14: Computability V (Prove by Reduction)

Design of Embedded Systems: Models, Validation and Synthesis (EE 249) Lecture 9

Compiling and Executing PDDL in Picat

THE AUSTRALIAN NATIONAL UNIVERSITY Second Semester COMP2600 (Formal Methods for Software Engineering)

Finite Automata Theory and Formal Languages TMV027/DIT321 LP Recap: Logic, Sets, Relations, Functions

7. The Recursion Theorem

An Introduction to Z3

Static Program Analysis

ITI Introduction to Computing II

Comp487/587 - Boolean Formulas

CSC D70: Compiler Optimization Static Single Assignment (SSA)

Formal Methods in Software Engineering

Nunchaku: Flexible Model Finding for Higher-Order Logic

ASYMPTOTIC COMPLEXITY SEARCHING/SORTING

Program Composition in Isabelle/UNITY

Assignment 0: Preparation /15-624/ Foundations of Cyber-Physical Systems

Dataflow Analysis. A sample program int fib10(void) { int n = 10; int older = 0; int old = 1; Simple Constant Propagation

Discrete Mathematics Review

Structure. Background. them to their higher order equivalents. functionals in Standard ML source code and converts

Foundations of Computation

Axiomatic Semantics. Semantics of Programming Languages course. Joosep Rõõmusaare

Probabilistic Guarded Commands Mechanized in HOL

7. The Recursion Theorem

Lecture 5: Sep. 23 &25

Reasoning with Quantified Boolean Formulas

Python. chrysn

Roy L. Crole. Operational Semantics Abstract Machines and Correctness. University of Leicester, UK

Blocking Synchronization: Streams Vijay Saraswat (Dec 10, 2012)

Modern Functional Programming and Actors With Scala and Akka

Assignment 4 - Solution

Notes on Inductive Sets and Induction

Introduction to Programming (Java) 3/12

Softwaretechnik. Lecture 13: Design by Contract. Peter Thiemann University of Freiburg, Germany

Softwaretechnik. Lecture 13: Design by Contract. Peter Thiemann University of Freiburg, Germany

Hoare Logic and Model Checking

Lectures on Separation Logic. Lecture 2: Foundations

Formal Reasoning CSE 331. Lecture 2 Formal Reasoning. Announcements. Formalization and Reasoning. Software Design and Implementation

Program verification using Hoare Logic¹

Why Functional Programming Matters. John Hughes & Mary Sheeran

Brief Introduction to Prolog

Hoare Logic I. Introduction to Deductive Program Verification. Simple Imperative Programming Language. Hoare Logic. Meaning of Hoare Triples

F 99 Final Quiz Solutions

An extension of HM(X) with bounded existential and universal data-types

FORCING WITH SEQUENCES OF MODELS OF TWO TYPES

CSE 331 Winter 2018 Homework 1

Meta-programming & you

Routing Algorithms. CS60002: Distributed Systems. Pallab Dasgupta Dept. of Computer Sc. & Engg., Indian Institute of Technology Kharagpur

Automatic Code Generation

Mid-Semester Quiz Second Semester, 2012

A Logic Primer. Stavros Tripakis University of California, Berkeley. Stavros Tripakis (UC Berkeley) EE 144/244, Fall 2014 A Logic Primer 1 / 35

Proof Calculus for Partial Correctness

ITI Introduction to Computing II

Software Analysis AdaCore

Model Checking & Program Analysis

Mathematical Foundations of Programming. Nicolai Kraus. Draft of February 15, 2018

Sequential programs. Uri Abraham. March 9, 2014

Turing Machine Recap

The Assignment Axiom (Hoare)

Introduction. In this talk

Universität Augsburg

What happens to the value of the expression x + y every time we execute this loop? while x>0 do ( y := y+z ; x := x:= x z )

Constraint Solving for Program Verification: Theory and Practice by Example

CpSc 421 Final Exam December 6, 2008

Software Engineering

CIS 4930/6930: Principles of Cyber-Physical Systems

CMSC 132, Object-Oriented Programming II Summer Lecture 12

Principles of Program Analysis: Control Flow Analysis

Anomaly Detection for the CERN Large Hadron Collider injection magnets

Verified Characteristic Formulae for CakeML. Armaël Guéneau, Magnus O. Myreen, Ramana Kumar, Michael Norrish April 18, 2017

Te s t D r i v e n D e v e l o p m e n t. C h a m i l J e e w a n t h a

7. The Recursion Theorem

Supplementary Material

UNIVERSITY OF CALIFORNIA, RIVERSIDE

Data Structures and Algorithms Chapter 2

Hoare Logic: Reasoning About Imperative Programs

Transcription:

DEBUGGING AND TESTING WITH SCALACHECK Martina Seidl 2017/11/14

Some Words on Scala Scala is object-oriented every value is an object classes and traits: types and behavior of objects inheritance Scala is functional every function is a value anonymous functions higher-order functions support of currying pattern matching Scala is statically typed generic classes, polymorphic methods variance annotations upper and lower type bounds 1/24

Scala By Example I (from [4]) class in Java: 1 p u b l i c class Person { 2 p u b l i c f i n a l S t r i n g name ; 3 p u b l i c f i n a l i n t age ; 4 Person ( S t r i n g name, i n t age ) { 5 t h i s. name = name ; 6 t h i s. age = age ; 7 } 8 } class in Scala: 1 class Person ( v a l name : String, 2 v a l age : I n t ) { } 2/24

Scala By Example I (from [4]) filtering in Java (before Java 8): 1 Person [ ] people ; Person [ ] minors ; Person [ ] a d u l t s ; 2... 3 A r r a y L i s t <Person> m i n o r s L i s t = 4 new A r r a y L i s t <Person > ( ) ; 5 A r r a y L i s t <Person> a d u l t s L i s t = 6 new A r r a y L i s t <Person > ( ) ; 7 f o r ( i n t i = 0; i < people. l e n g t h ; i ++) 8 ( people [ i ]. age < 18? m i n o r s L i s t : 9 a d u l t s L i s t ). add ( people [ i ] ) ; 10 minors = m i n o r s L i s t. toarray ( people ) ; 11 a d u l t s = a d u l t s L i s t. toarray ( people ) ; filtering in Scala: 1 v a l people : Array [ Person ] 2 v a l ( minors, a d u l t s ) = 3 people p a r t i t i o n ( _. age < 18) 3/24

Scala By Example II (adapted from [1]) 1 def s o r t ( xs : Array [ I n t ] ) { 2 3 def swap ( i : I n t, j : I n t ) { 4 v a l t = xs ( i ) ; xs ( i ) = xs ( j ) ; xs ( j ) = t 5 } 6 7 def s o r t 1 ( l : I n t, r : I n t ) { 8... 9 } 10 11 s o r t 1 ( 0, xs. l ength 1) 12 } 4/24

Scala By Example II (adapted from [1]) 1 def s o r t 1 ( l : I n t, r : I n t ) { 2 3 v a l p i v o t = xs ( ( l + r ) / 2) 4 var i = l ; var j = r 5 6 while ( i <= j ) { 7 while ( xs ( i ) < p i v o t ) i += 1 8 while ( xs ( j ) > p i v o t ) j = 1 9 i f ( i <= j ) { 10 swap ( i, j ) 11 i += 1 12 j = 1 13 } 14 } 15 16 i f ( j < r ) s o r t 1 ( i, r ) 17 } 5/24

Scala By Example II (adapted from [1]) 1 def s o r t ( xs : Array [ I n t ] ) : Array [ I n t ] = { 2 i f ( xs. length <= 1) xs 3 else { 4 5 v a l p i v o t = xs ( xs. l e n g t h / 2) 6 7 Array. concat ( 8 s o r t ( xs f i l t e r ( p i v o t <) ), 9 xs f i l t e r ( p i v o t ==), 10 s o r t ( xs f i l t e r ( p i v o t >) ) ) 11 } 12 } 6/24

The Power of Properties The specification of properties...... helps to understand what the program shall do... helps to understand what the program actually does... helps to talk about the program... can help to find an algorithm... is valuable for debugging 7/24

What does ScalaCheck do? User: specification of properties which should always hold definition of random data for testing properties no worries about missed test cases ScalaCheck: automatic generation of test cases checking if properties hold shrinking (minimization of failing test cases) 8/24

ScalaCheck is...... an automated, property based testing tool for Scala/Java... an extended port of Haskell QuickCheck... available at www.scalacheck.org first example: 1 o b j e c t MyProperties extends 2 P r o p e r t i e s ( " MyProperties " ) { 3 4 p r o p e r t y ( "same l e n g t h " ) = 5 f o r A l l { ( a : [ I n t ] ) => 6 a. l e n g t h == s o r t ( a ). l e n g t h 7 } 8 } 9/24

ScalaChecks Highlights automatic testing of properties automatic generation of test data precise control of test data generation automatic simplification of failing test cases support for stateful testing of command sequences simplification of failing command sequences direct testing of property object from the command scala> import org.scalacheck.prop.forall import org.scalacheck.prop.forall scala> val overflow = forall { (n: Int) => n > n-1 } overflow: org.scalacheck.prop = Prop scala> overflow.check! Falsified after 6 passed tests. > ARG_0: -2147483648 10/24

Basic Concepts properties org.scalacheck.prop generators org.scalacheck.gen test runner org.scalacheck.test 11/24

Property testable unit in ScalaCheck class: org.scalacheck.prop generation: specification of new property combination of other properties use specialized methods scala> object StringProps extends Properties("String") { property("startswith") = forall ( (a:string, b:string) => (a+b).startswith(a)) } defined module StringProps scala> StringProps.check + String.startsWith: OK, passed 100 tests. 12/24

Universally Quantified Property (Forall Property) create property: org.scalacheck.prop.forall in: function which returns Boolean or a property out: property check property: call of check method 1 import org. scalacheck. Prop. f o r A l l 2 3 v a l propreverselist = f o r A l l { 4 l : L i s t [ S t r i n g ] => 5 l. reverse. reverse == l } 6 7 v a l propconcatstring = f o r A l l { 8 ( s1 : String, s2 : S t r i n g ) => 9 ( s1 + s2 ). endswith ( s2 ) } 13/24

Data Generator generation of test data for custom data types subsets of standard data types representation: org.scalacheck.gen 1 v a l mygen = f o r { 2 n < Gen. choose (10,20) 3 m < Gen. choose ( 2 * n, 500) 4 } y i e l d ( n,m) 5 6 v a l vowel = Gen. oneof ( A, E, I, O, U ) 7 8 v a l vowel1 = Gen. frequency ( ( 3, A ), ( 4, E ), 9 ( 2, I ), ( 3, O ), ( 1, U ) ) 14/24

A Generator for Trees 1 sealed a b s t r a c t class Tree 2 case class Node ( l e f t : Tree, r i g h t : Tree, v : I n t ) extends Tree 3 case o b j e c t Leaf extends Tree 4 5 v a l genleaf = const ( Leaf ) 6 7 v a l gennode = f o r { 8 v < a r b i t r a r y [ I n t ] 9 l e f t < gentree 10 r i g h t < gentree 11 } y i e l d Node ( l e f t, r i g h t, v ) 12 13 def gentree : Gen [ Tree ] = oneof ( genleaf, gennode ) 15/24

Statistics on Test Data collect infos on created test data inspection of distribution only trivial test cases? 1 def ordered ( l : L i s t [ I n t ] ) = l == l. s o r t ( _ > _ ) 2 3 v a l myprop = f o r A l l { l : L i s t [ I n t ] => 4 c l a s s i f y ( ordered ( l ), " ordered " ) { 5 c l a s s i f y ( l. length > 5, " l a r g e ", " small " ) { 6 l. reverse. reverse == l 7... scala> myprop.check + OK, passed 100 tests. > Collected test data: 78% large 16% small, ordered 6% small 16/24

Conditional Properties sometimes specifications are implications implication operator restricts number of test cases problem: condition is hard or impossible to fulfill property does not only pass or fail, but could be undecided if implication condition does not get fulfilled. 1 p r o p e r t y ( " f i r s t E l e m e n t " ) = 2 Prop. f o r A l l { 3 ( xs : L i s t [ I n t ] ) => ( xs. size > 0) ==> 4 ( xs. head == xs ( 0 ) ) 5 } 17/24

Combining Properties combine existing properties to new ones val p1 = forall(...) val p2 = forall(...) val p3 = p1 && p2 val p4 = p1 p2 val p5 = p1 == p2 val p6 = all(p1, p2) // same as p1 && p2 val p7 = atleastone(p1, p2) // same as p1 p2 18/24

Test Case Execution Module Test execution of the tests generation of the arguments evaluation of the properties increase of size of test parameters reports success (passed) after certain number of tries Testing parameters in Test.Parameters number of times a property should be tested size bounds of test data number of tries in case of failure callback Statistics in Test.Result test properties with Test.check 19/24

Test Case Minimisation ScalaCheck tries to shrink failing test cases before they are reported Default by Prop.forAll No shrinking: Prop.forAllNoShrink 1 v a l p1 = f o r A l l N o S h r i n k ( a r b i t r a r y [ L i s t [ I n t ] ] ) ( 2 l => l == l. removeduplicates ) counter example: List(8, 0, -1, -3, -8, 8, 2, -10, 9, 1, -8) 1 v a l p3 = f o r A l l ( ( l : L i s t [ I n t ] ) => 2 l == l. removeduplicates ) counter example: List(-5, -5) 20/24

Customized Shrinking Definition of custom shrinking methods is possible Implicit method which returns Shrink[T ] instance Important: instances get smaller (otherwise loops possible) 1 i m p l i c i t def shrinktuple2 [ T1, T2 ] 2 ( i m p l i c i t s1 : Shrink [ T1 ], s2 : Shrink [ T2 ] 3 ) : Shrink [ ( T1, T2 ) ] = Shrink { case ( t1, t2 ) => 4 ( f o r ( x1 < s h r i n k ( t1 ) ) y i e l d ( x1, t2 ) ) append 5 ( f o r ( x2 < s h r i n k ( t2 ) ) y i e l d ( t1, x2 ) ) 6 } 21/24

State-Full Testing What about testing combinations of functions? Solution: org.scalacheck.commands Example: Test the behavior of a counter 1 class Counter { 2 p r i v a t e var n = 0 3 def i n c = n += 1 4 def dec = n = 1 5 def get = n 6 def r e s e t = n = 0 7 } 22/24

State-full Testing 1 2 o b j e c t C o u n t e r S p e c i f i c a t i o n extends Commands { 3 type State = I n t 4 type Sut = Counter 5 6 def newsut ( s t a t e : State ) : Sut = new Counter 7 8 9 case o b j e c t Inc extends UnitCommand { 10 def run ( sut : Sut ) : Unit = sut. i n c 11 def nextstate ( s t a t e : State ) : State = s t a t e + 1 12 def precondition ( s t a t e : State ) : Boolean = t r u e 13 def postcondition ( s t a t e : State, success : Boolean ) : Prop = success 14 } 15 16 17 } 23/24

References [1] M. Odersky. Scala By Example, EPFL, 2014 [2] ScalaCheck Project Site: www.scalacheck.org [3] Scala Project Site. ScalaCheck, http://www.scalacheck.org/ [4] M. Odersky. Scala: How to make best use of functions and objects, Tutorial slides, ACM SAC 2010 [5] R. Nilsson. ScalaCheck UserGuide, https://github.com/rickynils/scalacheck/blob/master/doc/userguide.md 24/24