Testing Abstract Data Structures with QuickCheck Thomas Arts Quviq AB / Chalmers.

Slides:



Advertisements
Similar presentations
More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules.
Advertisements

ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  Elements may appear more than once.
Semantics Static semantics Dynamic semantics attribute grammars
Modules Program is built out of components. Each component defines a set of logically related entities (strong internal coupling) A component has a public.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
Introducing Formal Methods, Module 1, Version 1.1, Oct., Formal Specification and Analytical Verification L 5.
© M. Winter COSC 4P41 – Functional Programming Testing vs Proving Testing –uses a set of “typical” examples, –symbolic testing, –may find errors,
String is a synonym for the type [Char].
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Introduction to ML – Part 1 Frances Spalding. Assignment 1 chive/fall05/cos441/assignments/a1.ht m
Using Types Slides thanks to Mark Jones. 2 Expressions Have Types: The type of an expression tells you what kind of value you might expect to see if you.
CSC1016 Coursework Clarification Derek Mortimer March 2010.
Katz Formal Specifications Larch 1 Algebraic Specification and Larch Formal Specifications of Complex Systems Shmuel Katz The Technion.
0 PROGRAMMING IN HASKELL Chapter 4 - Defining Functions.
Misc. Announcements Assignment available end of the day today –Due back in 11/03 (after break) Will also update slides on website –Today Midterm next week.
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.
IS 1181 IS 118 Introduction to Development Tools VB Chapter 03.
Exception Error handling. Exception 4 n An unusual occurrence during program execution that requires immediate handling n Errors are the most common type.
Using Types Slides thanks to Mark Jones. 2 Expressions Have Types: The type of an expression tells you what kind of value you might expect to see if you.
1 Joe Meehean. 2 Testing is the process of executing a program with the intent of finding errors. -Glenford Myers.
Fundamentals of Python: From First Programs Through Data Structures
CC0002NI – Computer Programming Computer Programming Er. Saroj Sharan Regmi Week 7.
Fundamentals of Python: First Programs
Chapter 12: Exception Handling
17-Sep-15 Erlang. Running Erlang Double-click on the Erlang icon, or type erl into a terminal (cmd) window You can try short pieces of code from here,
Erlang/QuickCheck Thomas Arts, IT University John Hughes, Chalmers University Gothenburg.
(or what I learned from Neil about software testing) John Hughes Chalmers University/Quviq AB.
CSE-321 Programming Languages Introduction to Functional Programming (Part II) POSTECH March 13, 2006 박성우.
Testing in Erlang. Different testing tools EUnit (standard lightweight xUnit solution for Erlang) Common Test (OTP based distributed testing tool) Qucik.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
Variables and ConstantstMyn1 Variables and Constants PHP stands for: ”PHP: Hypertext Preprocessor”, and it is a server-side programming language. Special.
Controlling Execution Programming Right from the Start with Visual Basic.NET 1/e 8.
COP-3330: Object Oriented Programming Flow Control May 16, 2012 Eng. Hector M Lugo-Cordero, MS.
Saeed Ghanbartehrani Summer 2015 Lecture Notes #5: Programming Structures IE 212: Computational Methods for Industrial Engineering.
Chapter 4 Making Decision Csc 125 C++ programming language Fall 2005.
Module 3: Steering&Arrays #1 2000/01Scientific Computing in OOCourse code 3C59 Module 3: Algorithm steering elements If, elseif, else Switch and enumerated.
Python uses boolean variables to evaluate conditions. The boolean values True and False are returned when an expression is compared or evaluated.
Chapter 7 Selection Dept of Computer Engineering Khon Kaen University.
I Power Higher Computing Software Development High Level Language Constructs.
Data Structures & Algorithms
Pascal Programming Iteration (looping) Carl Smith National Certificate Unit 4.
Function Definition by Cases and Recursion Lecture 2, Programmeringsteknik del A.
CSE 332: C++ Statements C++ Statements In C++ statements are basic units of execution –Each ends with ; (can use expressions to compute values) –Statements.
Understanding ADTs CSE 331 University of Washington.
1 Assertions. 2 A boolean expression or predicate that evaluates to true or false in every state In a program they express constraints on the state that.
CHAPTER 2 PROBLEM SOLVING USING C++ 1 C++ Programming PEG200/Saidatul Rahah.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
Today’s lecture Review of chapter 8 Go over examples.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Tevfik Bultan Lecture 4: Introduction to C: Control Flow.
(c) University of Washington10-1 CSC 143 Java Errors and Exceptions Reading: Ch. 15.
Faithful mapping of model classes to mathematical structures Ádám Darvas ETH Zürich Switzerland Peter Müller Microsoft Research Redmond, WA, USA SAVCBS.
Design by Contract. The Goal Ensure the correctness of our software (correctness) Recover when it is not correct anyway (robustness) Correctness: Assertions.
4 - Conditional Control Structures CHAPTER 4. Introduction A Program is usually not limited to a linear sequence of instructions. In real life, a programme.
Click to edit Master text styles Stacks Data Structure.
Compiler Design Lecture 10 Semantic Analysis. int aintegers int a[2][3]array(2, array(3, integer)) int f(int, float, char) int x float x char  int Int.
CSE-321 Programming Languages Introduction to Functional Programming POSTECH March 8, 2006 박성우.
Windows Programming Lecture 06. Data Types Classification Data types are classified in two categories that is, – those data types which stores decimal.
CSE 332: C++ Exceptions Motivation for C++ Exceptions Void Number:: operator/= (const double denom) { if (denom == 0.0) { // what to do here? } m_value.
Principles of programming languages 12: Functional programming
PL/pgSQL
ML: a quasi-functional language with strong typing
Type Definitions cs776 (prasad) L8tdef.
Erlang 15-Nov-18.
CSE 341 Section 5 Winter 2018.
Defining Classes and Methods
PROGRAMMING IN HASKELL
CSE-321 Programming Languages Introduction to Functional Programming
CSC 143 Java Errors and Exceptions.
PROGRAMMING IN HASKELL
Presentation transcript:

Testing Abstract Data Structures with QuickCheck Thomas Arts Quviq AB / Chalmers

Erlang shell 21> lists:seq(1,5).

Erlang shell 21> lists:seq(1,5). [1,2,3,4,5] 22> lists:seq(-3,12).

Erlang shell 21> lists:seq(1,5). [1,2,3,4,5] 22> lists:seq(-3,12). [-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12] 23> lists:seq(3,-4).

Erlang shell 21> lists:seq(1,5). [1,2,3,4,5] 22> lists:seq(-3,12). [-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12] 23> lists:seq(3,-4). ** exception error: no function clause matching lists:seq(3,-4) 24> lists:seq(3,3).

Erlang shell 21> lists:seq(1,5). [1,2,3,4,5] 22> lists:seq(-3,12). [-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12] 23> lists:seq(3,-4). ** exception error: no function clause matching lists:seq(3,-4) 24> lists:seq(3,3). [3] 25> lists:seq(3,2).

Erlang shell 21> lists:seq(1,5). [1,2,3,4,5] 22> lists:seq(-3,12). [-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12] 23> lists:seq(3,-4). ** exception error: no function clause matching lists:seq(3,-4) 24> lists:seq(3,3). [3] 25> lists:seq(3,2). []

Software is subject to change The functions lists:seq/1,2 return the empty list in a few cases when they used to generate an exception, for example lists:seq(1, 0). See lists(3) for details. (Thanks to Richard O'Keefe.) *** POTENTIAL INCOMPATIBILITY *** Own Id: OTP-7230

lists manual seq(From, To) -> Seq seq(From, To, Incr) -> Seq Returns a sequence of integers which starts with From and contains the successive results of adding Incr to the previous element, until To has been reached or passed (in the latter case, To is not an element of the sequence). Incr defaults to 1. Failure: If To<From-Incr and Incr is positive, or if To>From-Incr and Incr is negative, or if Incr==0 and From/=To. The following equalities hold for all sequences: length(lists:seq(From, To)) == To-From+1 length(lists:seq(From, To, Incr)) == (To-From+Incr) div Incr

Property prop_seq() -> ?FORALL({From,To,Incr},{int(),int(),int()}, case catch lists:seq(From,To,Incr) of {'EXIT',_} -> (To 0) orelse (To > From-Incr andalso Incr < 0) orelse (Incr==0 andalso From /= To); List when Incr /= 0 -> is_list(List) andalso length(List) == (To-From+Incr) div Incr end).

QuickCheck property eqc:quickcheck(lists_eqc:prop_seq()). Failed! Reason: {'EXIT',{badarith,[{lists_eqc,'-prop_seq/0-fun-0-',1}, {eqc_gen,gen,3}]}} After 1 tests. {0,0,0} false of course... you cannot divide by zero, but... > lists:seq(0,0,0). [0]

Property prop_seq() -> ?FORALL({From,To,Incr},{int(),int(),int()}, case catch lists:seq(From,To,Incr) of {'EXIT',_} -> (To 0) orelse (To > From-Incr andalso Incr < 0) orelse (Incr==0 andalso From /= To); List when Incr /= 0 -> is_list(List) andalso length(List) == (To-From+Incr) div Incr; [From] when Incr == 0 -> true end).

Moral 1.No matter how well you specify.... if you only write unit tests to validate your code, then you will forget a test case. 2.Even simple functions are worth checking with QuickCheck.

Data types QuickCheck for unit testing......data types as simple example

Data types Example of Erlang modules defining data types: queue.erl, dict.erl, sets.erl, digraph.erl, etc. Implementation of a data type: - implement a data structure, and - interface functions to manipulate data structure A type is defined... an opaque type.

Type annotations -opaque set() :: #set{}. -spec new() -> set(). -spec from_list([term()]) -> set(). -spec size(set()) -> non_neg_integer(). -spec to_list(set()) -> [term()]. Constructing a set Accessing a set

Type annotations -opaque set() :: #set{}. -spec new() -> set(). -spec from_list([term()]) -> set(). -spec size(set()) -> non_neg_integer(). -spec to_list(set()) -> [term()]. This is how one generates a set Use to create a set generator

From types to generators From –type and –spec annotations one can retrieve interface for generators 7> eqc_types:defining(sets). Defining type {set,0} {call,sets,new,[]} {call,sets,from_list,[list(term())]} {call,sets,add_element,[term(), set()]} {call,sets,del_element,[term(), set()]} {call,sets,union,[set(), set()]} {call,sets,union,[list(set())]} {call,sets,intersection,[set(), set()]} {call,sets,intersection,[non_empty(list(set())]} {call,sets,subtract,[set(), set()]} {call,sets,filter,[function1(bool()), set()]}

Generator Create a generator for the data type by calling a sequence of interface functions. The result of the generator is a symbolic term, that when evaluated creates the data structure. E.g.: {call,sets,intersection, [[{call,sets,union, [{call,sets,new,[]},{call,sets,from_list,[[-14,3,-9,10]]}]}, {call,sets,union, [{call,sets,from_list,[[-18,14,3,-3,3,7]]}, {call,sets,from_list,[[6,3,1,14]]}]}, {call,sets,subtract,[{call,sets,new,[]},{call,sets,new,[]}]}]]}

Properties What properties to write and how do we know we have written enough properties? Use a model interpretation! sets:f(Set) ≃ f_model( Set ) Example: sets:union(Set1,Set2) ≃ Set1 ∪ Set1 Set  turn the data structure set into a real set

Properties But we have no real sets, that’s why we implemented them in Erlang But we may have - a reference implementation (in any language) - a simple correct implementation, but inefficient implementation We use such implementation as our model

Model Set model(Set) -> lists:sort(sets:to_list(Set)). munion(S1,S2) -> lists:usort(S1++S2). madd_element(E,S) -> lists:usort([E|S]). etc

Type annotations -opaque set() :: #set{}. -spec new() -> set(). -spec from_list([term()]) -> set(). -spec size(set()) -> non_neg_integer(). -spec to_list(set()) -> [term()]. Any function that takes a set as argument defines a property.

Properties prop_add_element(G) -> ?FORALL({E,Set},{G,set(G)}, model(sets:add_element(E,eval(Set))) == madd_element(E,model(eval(Set)))). prop_union(G) -> ?FORALL({Set1,Set2},{set(G),set(G)}, model(sets:union(eval(Set1),eval(Set2))) == munion(model(eval(Set1)),model(eval(Set2)))). prop_size(G) -> ?FORALL(Set,set(G), sets:size(eval(Set)) == msize(model(eval(Set)))).

Properties But what about... filter(Pred, Set1) -> Set2 Types: Pred = fun (E) -> bool() Set1 = Set2 = set() Filter elements in Set1 with boolean function Fun.

Propeties prop_filter(G) -> ?FORALL({Pred,Set},{function1(bool()),set(G)}, model(sets:filter(Pred,eval(Set))) == mfilter(Pred,model(eval(Set)))). mfilter(Pred,S) -> [ E || E<-S, Pred(E)].

Summary Easy to use QuickCheck for testing data types Use type signatures to define generators Create a model interpretation Create a model function for each interface function Create a property for each interface function Guaranteed full test of the data structure