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

property based testing for better code
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1

@jessitron

Property Based Testing for Better Code

slide-2
SLIDE 2

lots of tests maintenance burden didn't test seams

slide-3
SLIDE 3

Scala ScalaCheck Property Based Testing

slide-4
SLIDE 4

Scala ScalaCheck Property Based Testing

slide-5
SLIDE 5
slide-6
SLIDE 6
slide-7
SLIDE 7
slide-8
SLIDE 8

Define Success

slide-9
SLIDE 9

Design Documentation Quality Enable Change

slide-10
SLIDE 10

Generators Properties

slide-11
SLIDE 11

Generators

slide-12
SLIDE 12

Generators

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

slide-13
SLIDE 13

Enable: tests of larger components

slide-14
SLIDE 14
slide-15
SLIDE 15
slide-16
SLIDE 16
slide-17
SLIDE 17
slide-18
SLIDE 18
slide-19
SLIDE 19
slide-20
SLIDE 20
slide-21
SLIDE 21

Game Rules # turns Player Player Strategy Strategy

slide-22
SLIDE 22

Rules

slide-23
SLIDE 23

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

slide-24
SLIDE 24

property("The game is fair") = forAll {(rules: Rules, moves: MoveSet) => val oneWay = Rules.score(rules, moves) val theOtherWay = Rules.score(rules, moves.swap)

  • neWay.swap == theOtherWay

}

  • bject RuleTest extends Properties("Prisoners Dilemma") {

}

slide-25
SLIDE 25

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

}

  • bject RuleTest extends Properties("Prisoners Dilemma") {

}

slide-26
SLIDE 26

A => B

slide-27
SLIDE 27

Properties

slide-28
SLIDE 28

Properties

Document: what is important? Quality: they are always true

slide-29
SLIDE 29

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)

}

slide-30
SLIDE 30

Complete properties Incomplete properties Relational properties

slide-31
SLIDE 31

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

slide-32
SLIDE 32

forAll { (input: Input) =>

  • ldWay(input) =? newWay(input)

}

slide-33
SLIDE 33

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

slide-34
SLIDE 34

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" }}}

slide-35
SLIDE 35
slide-36
SLIDE 36

Properties

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

slide-37
SLIDE 37

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

slide-38
SLIDE 38

Scala ScalaCheck Property Based Testing

slide-39
SLIDE 39

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

slide-40
SLIDE 40

@jessitron

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