property based testing for better code
play

Property Based Testing for Better Code @jessitron lots of tests - PowerPoint PPT Presentation

Property Based Testing for Better Code @jessitron lots of tests maintenance burden didn't test seams Scala ScalaCheck Property Based Testing Scala ScalaCheck Property Based Testing Define Success Design Documentation Quality Enable


  1. Property Based Testing for Better Code @jessitron

  2. lots of tests maintenance burden didn't test seams

  3. Scala ScalaCheck Property Based Testing

  4. Scala ScalaCheck Property Based Testing

  5. Define Success

  6. Design Documentation Quality Enable Change

  7. Generators Properties

  8. Generators

  9. Generators Document: what is valid input data? Quality: automatic corner cases Design: build up from components Enable: tests of larger components

  10. Enable: tests of larger components

  11. Game Rules # turns Player Player Strategy Strategy

  12. Rules

  13. case class Rules(temptationToDefect: Points, rewardForMutualCooperation: Points, punishmentForMutualDefection: Points, suckersPenalty: Points)

  14. object RuleTest extends Properties("Prisoners Dilemma") { property("The game is fair") = forAll {(rules: Rules, moves: MoveSet) => val oneWay = Rules.score(rules, moves) val theOtherWay = Rules.score(rules, moves.swap) � oneWay.swap == theOtherWay } }

  15. object RuleTest extends Properties("Prisoners Dilemma") { property("Defection is always better for me") = forAll {(rules: Rules, theirMove: Move) => val ifIDefect = Rules.score(rules, (Defect, theirMove))._1 val ifICooperate = Rules.score(rules, (Cooperate, theirMove))._1 � ifIDefect > ifICooperate } }

  16. A => B

  17. Properties

  18. Properties Quality: they are always true Document: what is important?

  19. property("The sucker always cooperates") = forAll (strategyGen, Gen.posNum[Int]) { (opponent: Strategy, turns: Int) => val allMoves:Stream[MoveSet] = Strategy.moves(Strategy.sucker, opponent).take(turns) val myMoves = allMoves.map (_._1) � myMoves.forall(_ == Cooperate) }

  20. Complete properties Incomplete properties Relational properties

  21. forAll { (list: List[Int] => list.reverse.reverse = list }

  22. forAll { (input: Input) => oldWay(input) =? newWay(input) }

  23. forAll { (output: Output) => val input = from(output) subject(input) ?= output }

  24. property("All games end within the time limit") = forAll { (rules: Rules, players: Seq[Player], limit: Duration) => classify(players.size < 10, "small", "large") { val timer = new Timer() val output = Game.eachOnEach(rules)(sys, players, limit) val timeTaken = timer.check val timeOver = timeTaken - limit � classify (timeOver < (fudge/2), "comfortable", "barely") { (timeTaken <= (limit + fudge)) :| s"$timeTaken was longer than $limit" }}}

  25. Properties Quality: they are always true Document: what is important? Enable: changes to less important bits Design: what do we need to know?

  26. What does it make free? What does it make explicit? What does it make impossible?

  27. Scala ScalaCheck Property Based Testing

  28. http://www.artima.com/shop/scalacheck

  29. https://github.com/jessitron/scalacheck-prisoners-dilemma @jessitron

Recommend


More recommend