SlideShare uma empresa Scribd logo
1 de 29
Baixar para ler offline
Beyond xUnit example-based testing:
property-based testing with ScalaCheck

              Franklin Chen
        http://franklinchen.com/



          Pittsburgh Scala Meetup
               April 11, 2013
Our goal: software correctness



   Use all available tools that are practical in context.
        Static type system
             We are Scala users!
        Two extremes
             Automated theorem proving
             Testing
   What is practical?
Theorem proving


   Example: list append
   // Given an implementation in ListOps of:
   def append[A](xs: List[A], ys: List[A]): List[A]

   How prove this property without a shadow of a doubt?
   // for all lists xs and ys
   ListOps.append(xs, ys).length == xs.length + y.length

   Not (yet) practical in most contexts.
   (Scala compiler cannot prove this property.)
More powerful static type system: dependent types

   Try using a more powerful language?
       Example: Idris language, based on Haskell

   Type checks!
   (++) : Vect A n -> Vect A m -> Vect A (n + m)
   (++) Nil       ys = ys
   (++) (x :: xs) ys = x :: xs ++ ys

   Still research, however.
       Also: Scala libraries such as shapeless pushing the edge of
       Scala’s type system.
       Not (yet) practical for most of us.
Testing



   Goals?
       Give up goal of mathematical guarantee of correctness.
       Try to gain confidence that our code might be “probably” or
       “mostly” correct.
       Still a young field. Recent report on the state of testing: SEI
       blog
   Remember to be humble when testing; avoid overconfidence!
Example-based testing




       xUnit frameworks such as JUnit
       Hand-craft specific example scenarios, make assertions
   Popular Scala test frameworks that support xUnit style testing:
       ScalaTest
       specs2
   For concreteness: I test with specs2, with SBT.
Individual examples of list append



   // Individually hand-crafted examples
   ListOps.append(List(3), List(7, 2)).length must_==
     List(3).length + List(7, 2).length
   ListOps.append(List(3, 4), List(7, 2)).length must_==
     List(3, 4).length + List(7, 2).length
   // ...

       Tedious to set up each example, one by one.
       Are we confident that we listed all the relevant cases,
       including corner cases?
Refactoring to a data table



   // Hand-crafted table of data, but logic is factored out
   "xs"       | "ys"       |
   List(3)    ! List(7, 2) |
   List(3, 4) ! List(7, 2) |> {
     (xs, ys) =>
     ListOps.append(xs, ys).length must_==
       xs.length + ys.length
   }
   Note: latest JUnit supports parameterized tests also.
Property-based testing: introducing ScalaCheck


       ScalaCheck library
           Port of Haskell QuickCheck
           Use standalone, or within ScalaTest or specs2
       Write down what we really intend, a universal property!
   prop {
     (xs: List[Int], ys: List[Int]) =>
     ListOps.append(xs, ys).length must_==
       xs.length + ys.length
   }
   ScalaCheck automatically generates 100 random test cases (the
   default number) and runs them successfully!
Property-based testing: fake theorem proving?



        Theorem proving is hard.
        ScalaCheck allows us to pretend we are theorem proving,
        with caveats:
             How   random are the generated data?
             How   useful for our desired corner cases?
             How   can we customize the generation?
             How   reproducible is the test run?
             How   confident can we be in the coverage?
   Property-based testing is still an area of research.
   But it is already useful as it is.
A failing test reports a minimal counter-example


   What is wrong with this property about multiplication and division?
   prop {
     (x: Int, y: Int) => (x * y) / y must_== x
   }
   Output:
   > test
   ArithmeticException: A counter-example is [0, 0]:
     java.lang.ArithmeticException: / by zero
   Oops, our test was sloppy!
Introducing conditional properties

   Exclude dividing by 0: use conditional operator ==> with forAll:
   prop {
     x: Int =>
     forAll {
       y: Int =>
       (y != 0) ==> { (x * y) / y must_== x             }
     }
   }

       Generate random x.
       Generate random y, but discard test case if conditions fails.
   All good now?
Testing as an iterative process



       Still get a counter-example.
       Int overflow.
   > test
   A counter-example is [2, 1073741824]
     (after 2 tries - shrinked
      (’452994647’ -> ’2’,’-2147483648’ -> ’1073741824’))
   ’-2’ is not equal to ’2’
   Writing and refining a property guides our understanding of the
   problem.
The joy of experimental testing



   ScalaCheck discovered an unexpected edge case for us!
       Write a general property before coding.
       Write the code.
       ScalaCheck gives counter-example.
       Choice:
           Fix code.
           Fix property.
       Run ScalaCheck again until test passes.
Choice 1: fix code


   Assume we want our high-level property, of multiplying and
   dividing of integers, to hold.
   Choose a different representation of integer in our application:
   replace Int with BigInt:
   prop {
     x: BigInt =>
     forAll {
       y: BigInt =>
       (y != 0) ==> { (x * y) / y must_== x             }
     }
   }
   Success!
Choice 2: fix property




   Assume we only care about a limited range of Int.
   Use a generator Gen.choose, for example:
   forAll(Gen.choose(0, 10000), Gen.choose(1, 10000)) {
     (x: Int, y: Int) => { (x * y) / y must_== x }
   }
   Success!
Introduction to custom generators: why?


   Attempted property:
   prop {
     (x: Int, y: Int, z: Int) =>
     (x < y && y < z) ==> x < z
   }
   Output:
   > test
   Gave up after only 28 passed tests.
     142 tests were discarded.
   Reason: too many x, y, z test cases that did not satisfy the
   condition.
Introduction to custom generators: how?

   Try to generate data likely to be useful for the property.
   Use arbitrary generator, Gen.choose generator, and
   for-comprehension:
   val orderedTriples = for {
     x <- arbitrary[Int]
     y <- Gen.choose(x + 1, Int.MaxValue)
     z <- Gen.choose(y + 1, Int.MaxValue)
   } yield (x, y, z)

   forAll(orderedTriples) {
     case (x, y, z) =>
     (x < y && y < z) ==> x < z
   }
   Success!
More complex custom generator: sorted lists


   Assume we want to specify the behavior of a function that inserts
   an integer into a sorted list to return a new sorted list:
   def insert(x: Int, xs: List[Int]): List[Int]
   We first try
   prop {
     (x: Int, xs: List[Int]) =>
     isSorted(xs) ==> isSorted(insert(x, xs))
   }
   where we have already defined
   def isSorted(xs: List[Int]): Boolean
Not constrained enough

   Too many generated lists are not sorted.
   > test-only *ListCheckSpec
   Gave up after only 10 passed tests.
     91 tests were discarded.
   So let’s write a custom generator someSortedLists, to use with
   the property
   forAll(someSortedLists) {
     xs: List[Int] => prop {
       x: Int =>
       isSorted(xs) ==> isSorted(insert(x, xs))
     }
   }
Custom generator for sorted lists



       Choose a list size.
       Choose a starting integer x.
       Choose a list with first element at least x.
   val someSortedLists = for {
     size <- Gen.choose(0, 1000)
     x <- arbitrary[Int]
     xs <- sortedListsFromAtLeast(size, x)
   } yield xs
   Now implement our sortedListsFromAtLeast.
Generating the sorted list
   /**
      @return generator of a sorted list of length size
              with first element >= x
     */
   def sortedListsFromAtLeast(size: Int, x: Int):
        Gen[List[Int]] = {
      if (size == 0) {
        Nil
      }
      else {
        for {
          y <- Gen.choose(x, x+100)
          ys <- sortedListsFromAtLeast(size-1, y)
        } yield y::ys
      }
   }
What is going on? Classifiers
   Gather statistics about the nature of the generated data. One way:
   classifiers.
   forAll(someSortedLists) {
     xs: List[Int] => classify(xs.length < 300,
                               "length 0-299") {
       classify(xs.length >= 300 && xs.length < 800,
                "length 300-799") {
         classify(xs.length >= 800,
                  "length 800+") {
           prop {
             x: Int =>
             isSorted(xs) ==> isSorted(insert(x, xs))
           }
         }
       }
     }
   }
Classifier output




   Output:
   > test-only *ListCheckSpec
   [info] > Collected test data:
   [info] 42% length 300-799
   [info] 31% length 0-299
   [info] 27% length 800+
Much more!



  Examples not covered today.
      Built-in support for generating sized containers.
      Specify custom frequencies when choosing alternatives.
      Generate objects such as trees.
      Generate functions.
      Supply own random number generator.
      Stateful testing.
Warning: false sense of security




       Automated testing: good
       Lots and lots of tests: good?
       Fallacy of big data overoptimism
   Testing is not proof: absence of evidence of bugs does not equal
   evidence of absence of bugs.
Other property-based testing tools



   ScalaCheck has known limitations:
       Not always easy to write good generator.
       Random generation does not provide complete coverage.
       Tests do not give the same results when run again.
   Alternatives:
        SmallCheck for Haskell
            Apparently ported to Scala
       Active area of research
The TDD community




     JUnit incorporating some property-based ideas in the new
     feature called Theories
     Many other programming languages gaining property-based
     testing!
     Nat Pryce of Growing Obect-Oriented Software Guided by
     Tests giving workshops on property-based TDD
Conclusion



      Automated testing is good.
      Property-based testing: put into your toolbox.
             If you use Scala: use ScalaCheck.
             If you use Java: use ScalaCheck!
      Be aware of limitations of testing.
      Have fun!
   All materials for this talk available at
   https://github.com/franklinchen/talk-on-scalacheck.

Mais conteúdo relacionado

Mais procurados

An Introduction to Property Based Testing
An Introduction to Property Based TestingAn Introduction to Property Based Testing
An Introduction to Property Based TestingC4Media
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Andrei Savu
 
Java Generics
Java GenericsJava Generics
Java Genericsjeslie
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from javaIndicThreads
 
An introduction to property based testing
An introduction to property based testingAn introduction to property based testing
An introduction to property based testingScott Wlaschin
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsFrançois Garillot
 
Ruslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testingRuslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testingIevgenii Katsan
 
Python Puzzlers - 2016 Edition
Python Puzzlers - 2016 EditionPython Puzzlers - 2016 Edition
Python Puzzlers - 2016 EditionNandan Sawant
 
Ti1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismTi1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismEelco Visser
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako, Vasil Remeniuk
 
Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Jay Coskey
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in ScalaKnoldus Inc.
 

Mais procurados (20)

Java generics final
Java generics finalJava generics final
Java generics final
 
An Introduction to Property Based Testing
An Introduction to Property Based TestingAn Introduction to Property Based Testing
An Introduction to Property Based Testing
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1
 
Nalinee java
Nalinee javaNalinee java
Nalinee java
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
 
An introduction to property based testing
An introduction to property based testingAn introduction to property based testing
An introduction to property based testing
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on Steroids
 
Java
JavaJava
Java
 
Ruslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testingRuslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testing
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Python Puzzlers - 2016 Edition
Python Puzzlers - 2016 EditionPython Puzzlers - 2016 Edition
Python Puzzlers - 2016 Edition
 
Ti1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismTi1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: Polymorphism
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako,
 
Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13Introduction to Haskell: 2011-04-13
Introduction to Haskell: 2011-04-13
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Unit Testing with Foq
Unit Testing with FoqUnit Testing with Foq
Unit Testing with Foq
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
 

Destaque

Englishtestunit73 eso d-2
Englishtestunit73 eso d-2Englishtestunit73 eso d-2
Englishtestunit73 eso d-2Vicky
 
Ll bean huntingboot
Ll bean huntingbootLl bean huntingboot
Ll bean huntingbootjessradio
 
Accelerated reader in_grades_3-5 mod 8.11
Accelerated reader in_grades_3-5 mod 8.11Accelerated reader in_grades_3-5 mod 8.11
Accelerated reader in_grades_3-5 mod 8.11Leah Vestal
 
The ancient middle east mesopotamian literature2
The ancient middle east  mesopotamian literature2The ancient middle east  mesopotamian literature2
The ancient middle east mesopotamian literature2sparky31522
 
Physical Science: Chapter 4, sec 2
Physical Science: Chapter 4, sec 2Physical Science: Chapter 4, sec 2
Physical Science: Chapter 4, sec 2mshenry
 
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...william.m.thomson
 
Halifax’s Finance and Insurance Industry: Our Opportunity
Halifax’s Finance and Insurance Industry: Our OpportunityHalifax’s Finance and Insurance Industry: Our Opportunity
Halifax’s Finance and Insurance Industry: Our OpportunityHalifax Partnership
 
FiftyYears_Mottram_s
FiftyYears_Mottram_sFiftyYears_Mottram_s
FiftyYears_Mottram_sNigel Mottram
 
Caching Search Engine Results over Incremental Indices
Caching Search Engine Results over Incremental IndicesCaching Search Engine Results over Incremental Indices
Caching Search Engine Results over Incremental IndicesRoi Blanco
 
森下・アジャイル研究所LIVE 森下 真衣
森下・アジャイル研究所LIVE  森下 真衣森下・アジャイル研究所LIVE  森下 真衣
森下・アジャイル研究所LIVE 森下 真衣pgcafe
 
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD Index
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD IndexDiabetes For Dummies, 3rd Edition by Alan L. Rubin, MD Index
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD IndexAlanLRubinMD
 
Networking 101 - Building Relationships
Networking 101 - Building RelationshipsNetworking 101 - Building Relationships
Networking 101 - Building RelationshipsHalifax Partnership
 
Web 2.0..Business Friend or Foe?
Web 2.0..Business Friend or Foe?Web 2.0..Business Friend or Foe?
Web 2.0..Business Friend or Foe?Stites & Harbison
 
Earth Science: Chapter 2: lesson 2 Rocks
Earth Science: Chapter 2: lesson 2 RocksEarth Science: Chapter 2: lesson 2 Rocks
Earth Science: Chapter 2: lesson 2 Rocksmshenry
 
Physical Science: Chapter 3 sec3
Physical Science: Chapter 3 sec3Physical Science: Chapter 3 sec3
Physical Science: Chapter 3 sec3mshenry
 

Destaque (20)

Exuma corp deck
Exuma corp deckExuma corp deck
Exuma corp deck
 
Englishtestunit73 eso d-2
Englishtestunit73 eso d-2Englishtestunit73 eso d-2
Englishtestunit73 eso d-2
 
Ll bean huntingboot
Ll bean huntingbootLl bean huntingboot
Ll bean huntingboot
 
Accelerated reader in_grades_3-5 mod 8.11
Accelerated reader in_grades_3-5 mod 8.11Accelerated reader in_grades_3-5 mod 8.11
Accelerated reader in_grades_3-5 mod 8.11
 
The ancient middle east mesopotamian literature2
The ancient middle east  mesopotamian literature2The ancient middle east  mesopotamian literature2
The ancient middle east mesopotamian literature2
 
Physical Science: Chapter 4, sec 2
Physical Science: Chapter 4, sec 2Physical Science: Chapter 4, sec 2
Physical Science: Chapter 4, sec 2
 
Pres
PresPres
Pres
 
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...
The Fight for Marjah - Recent Counterinsurgency Operations In Southern Afghan...
 
Gic2011 aula05-ingles
Gic2011 aula05-inglesGic2011 aula05-ingles
Gic2011 aula05-ingles
 
Presentation1
Presentation1Presentation1
Presentation1
 
Halifax’s Finance and Insurance Industry: Our Opportunity
Halifax’s Finance and Insurance Industry: Our OpportunityHalifax’s Finance and Insurance Industry: Our Opportunity
Halifax’s Finance and Insurance Industry: Our Opportunity
 
FiftyYears_Mottram_s
FiftyYears_Mottram_sFiftyYears_Mottram_s
FiftyYears_Mottram_s
 
Caching Search Engine Results over Incremental Indices
Caching Search Engine Results over Incremental IndicesCaching Search Engine Results over Incremental Indices
Caching Search Engine Results over Incremental Indices
 
森下・アジャイル研究所LIVE 森下 真衣
森下・アジャイル研究所LIVE  森下 真衣森下・アジャイル研究所LIVE  森下 真衣
森下・アジャイル研究所LIVE 森下 真衣
 
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD Index
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD IndexDiabetes For Dummies, 3rd Edition by Alan L. Rubin, MD Index
Diabetes For Dummies, 3rd Edition by Alan L. Rubin, MD Index
 
Networking 101 - Building Relationships
Networking 101 - Building RelationshipsNetworking 101 - Building Relationships
Networking 101 - Building Relationships
 
Web 2.0..Business Friend or Foe?
Web 2.0..Business Friend or Foe?Web 2.0..Business Friend or Foe?
Web 2.0..Business Friend or Foe?
 
Gic2011 aula3-ingles
Gic2011 aula3-inglesGic2011 aula3-ingles
Gic2011 aula3-ingles
 
Earth Science: Chapter 2: lesson 2 Rocks
Earth Science: Chapter 2: lesson 2 RocksEarth Science: Chapter 2: lesson 2 Rocks
Earth Science: Chapter 2: lesson 2 Rocks
 
Physical Science: Chapter 3 sec3
Physical Science: Chapter 3 sec3Physical Science: Chapter 3 sec3
Physical Science: Chapter 3 sec3
 

Semelhante a Beyond xUnit example-based testing: property-based testing with ScalaCheck

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
Be smart when testing your Akka code
Be smart when testing your Akka codeBe smart when testing your Akka code
Be smart when testing your Akka codeMykhailo Kotsur
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
 
Introducing Pattern Matching in Scala
 Introducing Pattern Matching  in Scala Introducing Pattern Matching  in Scala
Introducing Pattern Matching in ScalaAyush Mishra
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scalashinolajla
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testingVincent Pradeilles
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scalaehsoon
 
Lecture_3.5-Array_Type Conversion_Math Class.pptx
Lecture_3.5-Array_Type Conversion_Math Class.pptxLecture_3.5-Array_Type Conversion_Math Class.pptx
Lecture_3.5-Array_Type Conversion_Math Class.pptxShahinAhmed49
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An IntroductionManvendra Singh
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
ScalaCheck
ScalaCheckScalaCheck
ScalaCheckBeScala
 

Semelhante a Beyond xUnit example-based testing: property-based testing with ScalaCheck (20)

(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Be smart when testing your Akka code
Be smart when testing your Akka codeBe smart when testing your Akka code
Be smart when testing your Akka code
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
 
Introducing Pattern Matching in Scala
 Introducing Pattern Matching  in Scala Introducing Pattern Matching  in Scala
Introducing Pattern Matching in Scala
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
 
Scala - core features
Scala - core featuresScala - core features
Scala - core features
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
 
Lecture_3.5-Array_Type Conversion_Math Class.pptx
Lecture_3.5-Array_Type Conversion_Math Class.pptxLecture_3.5-Array_Type Conversion_Math Class.pptx
Lecture_3.5-Array_Type Conversion_Math Class.pptx
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An Introduction
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
ScalaCheck
ScalaCheckScalaCheck
ScalaCheck
 

Último

Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 

Último (20)

Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 

Beyond xUnit example-based testing: property-based testing with ScalaCheck

  • 1. Beyond xUnit example-based testing: property-based testing with ScalaCheck Franklin Chen http://franklinchen.com/ Pittsburgh Scala Meetup April 11, 2013
  • 2. Our goal: software correctness Use all available tools that are practical in context. Static type system We are Scala users! Two extremes Automated theorem proving Testing What is practical?
  • 3. Theorem proving Example: list append // Given an implementation in ListOps of: def append[A](xs: List[A], ys: List[A]): List[A] How prove this property without a shadow of a doubt? // for all lists xs and ys ListOps.append(xs, ys).length == xs.length + y.length Not (yet) practical in most contexts. (Scala compiler cannot prove this property.)
  • 4. More powerful static type system: dependent types Try using a more powerful language? Example: Idris language, based on Haskell Type checks! (++) : Vect A n -> Vect A m -> Vect A (n + m) (++) Nil ys = ys (++) (x :: xs) ys = x :: xs ++ ys Still research, however. Also: Scala libraries such as shapeless pushing the edge of Scala’s type system. Not (yet) practical for most of us.
  • 5. Testing Goals? Give up goal of mathematical guarantee of correctness. Try to gain confidence that our code might be “probably” or “mostly” correct. Still a young field. Recent report on the state of testing: SEI blog Remember to be humble when testing; avoid overconfidence!
  • 6. Example-based testing xUnit frameworks such as JUnit Hand-craft specific example scenarios, make assertions Popular Scala test frameworks that support xUnit style testing: ScalaTest specs2 For concreteness: I test with specs2, with SBT.
  • 7. Individual examples of list append // Individually hand-crafted examples ListOps.append(List(3), List(7, 2)).length must_== List(3).length + List(7, 2).length ListOps.append(List(3, 4), List(7, 2)).length must_== List(3, 4).length + List(7, 2).length // ... Tedious to set up each example, one by one. Are we confident that we listed all the relevant cases, including corner cases?
  • 8. Refactoring to a data table // Hand-crafted table of data, but logic is factored out "xs" | "ys" | List(3) ! List(7, 2) | List(3, 4) ! List(7, 2) |> { (xs, ys) => ListOps.append(xs, ys).length must_== xs.length + ys.length } Note: latest JUnit supports parameterized tests also.
  • 9. Property-based testing: introducing ScalaCheck ScalaCheck library Port of Haskell QuickCheck Use standalone, or within ScalaTest or specs2 Write down what we really intend, a universal property! prop { (xs: List[Int], ys: List[Int]) => ListOps.append(xs, ys).length must_== xs.length + ys.length } ScalaCheck automatically generates 100 random test cases (the default number) and runs them successfully!
  • 10. Property-based testing: fake theorem proving? Theorem proving is hard. ScalaCheck allows us to pretend we are theorem proving, with caveats: How random are the generated data? How useful for our desired corner cases? How can we customize the generation? How reproducible is the test run? How confident can we be in the coverage? Property-based testing is still an area of research. But it is already useful as it is.
  • 11. A failing test reports a minimal counter-example What is wrong with this property about multiplication and division? prop { (x: Int, y: Int) => (x * y) / y must_== x } Output: > test ArithmeticException: A counter-example is [0, 0]: java.lang.ArithmeticException: / by zero Oops, our test was sloppy!
  • 12. Introducing conditional properties Exclude dividing by 0: use conditional operator ==> with forAll: prop { x: Int => forAll { y: Int => (y != 0) ==> { (x * y) / y must_== x } } } Generate random x. Generate random y, but discard test case if conditions fails. All good now?
  • 13. Testing as an iterative process Still get a counter-example. Int overflow. > test A counter-example is [2, 1073741824] (after 2 tries - shrinked (’452994647’ -> ’2’,’-2147483648’ -> ’1073741824’)) ’-2’ is not equal to ’2’ Writing and refining a property guides our understanding of the problem.
  • 14. The joy of experimental testing ScalaCheck discovered an unexpected edge case for us! Write a general property before coding. Write the code. ScalaCheck gives counter-example. Choice: Fix code. Fix property. Run ScalaCheck again until test passes.
  • 15. Choice 1: fix code Assume we want our high-level property, of multiplying and dividing of integers, to hold. Choose a different representation of integer in our application: replace Int with BigInt: prop { x: BigInt => forAll { y: BigInt => (y != 0) ==> { (x * y) / y must_== x } } } Success!
  • 16. Choice 2: fix property Assume we only care about a limited range of Int. Use a generator Gen.choose, for example: forAll(Gen.choose(0, 10000), Gen.choose(1, 10000)) { (x: Int, y: Int) => { (x * y) / y must_== x } } Success!
  • 17. Introduction to custom generators: why? Attempted property: prop { (x: Int, y: Int, z: Int) => (x < y && y < z) ==> x < z } Output: > test Gave up after only 28 passed tests. 142 tests were discarded. Reason: too many x, y, z test cases that did not satisfy the condition.
  • 18. Introduction to custom generators: how? Try to generate data likely to be useful for the property. Use arbitrary generator, Gen.choose generator, and for-comprehension: val orderedTriples = for { x <- arbitrary[Int] y <- Gen.choose(x + 1, Int.MaxValue) z <- Gen.choose(y + 1, Int.MaxValue) } yield (x, y, z) forAll(orderedTriples) { case (x, y, z) => (x < y && y < z) ==> x < z } Success!
  • 19. More complex custom generator: sorted lists Assume we want to specify the behavior of a function that inserts an integer into a sorted list to return a new sorted list: def insert(x: Int, xs: List[Int]): List[Int] We first try prop { (x: Int, xs: List[Int]) => isSorted(xs) ==> isSorted(insert(x, xs)) } where we have already defined def isSorted(xs: List[Int]): Boolean
  • 20. Not constrained enough Too many generated lists are not sorted. > test-only *ListCheckSpec Gave up after only 10 passed tests. 91 tests were discarded. So let’s write a custom generator someSortedLists, to use with the property forAll(someSortedLists) { xs: List[Int] => prop { x: Int => isSorted(xs) ==> isSorted(insert(x, xs)) } }
  • 21. Custom generator for sorted lists Choose a list size. Choose a starting integer x. Choose a list with first element at least x. val someSortedLists = for { size <- Gen.choose(0, 1000) x <- arbitrary[Int] xs <- sortedListsFromAtLeast(size, x) } yield xs Now implement our sortedListsFromAtLeast.
  • 22. Generating the sorted list /** @return generator of a sorted list of length size with first element >= x */ def sortedListsFromAtLeast(size: Int, x: Int): Gen[List[Int]] = { if (size == 0) { Nil } else { for { y <- Gen.choose(x, x+100) ys <- sortedListsFromAtLeast(size-1, y) } yield y::ys } }
  • 23. What is going on? Classifiers Gather statistics about the nature of the generated data. One way: classifiers. forAll(someSortedLists) { xs: List[Int] => classify(xs.length < 300, "length 0-299") { classify(xs.length >= 300 && xs.length < 800, "length 300-799") { classify(xs.length >= 800, "length 800+") { prop { x: Int => isSorted(xs) ==> isSorted(insert(x, xs)) } } } } }
  • 24. Classifier output Output: > test-only *ListCheckSpec [info] > Collected test data: [info] 42% length 300-799 [info] 31% length 0-299 [info] 27% length 800+
  • 25. Much more! Examples not covered today. Built-in support for generating sized containers. Specify custom frequencies when choosing alternatives. Generate objects such as trees. Generate functions. Supply own random number generator. Stateful testing.
  • 26. Warning: false sense of security Automated testing: good Lots and lots of tests: good? Fallacy of big data overoptimism Testing is not proof: absence of evidence of bugs does not equal evidence of absence of bugs.
  • 27. Other property-based testing tools ScalaCheck has known limitations: Not always easy to write good generator. Random generation does not provide complete coverage. Tests do not give the same results when run again. Alternatives: SmallCheck for Haskell Apparently ported to Scala Active area of research
  • 28. The TDD community JUnit incorporating some property-based ideas in the new feature called Theories Many other programming languages gaining property-based testing! Nat Pryce of Growing Obect-Oriented Software Guided by Tests giving workshops on property-based TDD
  • 29. Conclusion Automated testing is good. Property-based testing: put into your toolbox. If you use Scala: use ScalaCheck. If you use Java: use ScalaCheck! Be aware of limitations of testing. Have fun! All materials for this talk available at https://github.com/franklinchen/talk-on-scalacheck.