github.com/leanovate/gopter@v0.2.9/commands/example_commands_test.go (about) 1 package commands_test 2 3 import ( 4 "github.com/leanovate/gopter" 5 "github.com/leanovate/gopter/commands" 6 "github.com/leanovate/gopter/gen" 7 ) 8 9 type BuggyCounter struct { 10 n int 11 } 12 13 func (c *BuggyCounter) Inc() { 14 c.n++ 15 } 16 17 func (c *BuggyCounter) Dec() { 18 if c.n > 3 { 19 // Intentional error 20 c.n -= 2 21 } else { 22 c.n-- 23 } 24 } 25 26 func (c *BuggyCounter) Get() int { 27 return c.n 28 } 29 30 func (c *BuggyCounter) Reset() { 31 c.n = 0 32 } 33 34 var GetBuggyCommand = &commands.ProtoCommand{ 35 Name: "GET", 36 RunFunc: func(systemUnderTest commands.SystemUnderTest) commands.Result { 37 return systemUnderTest.(*BuggyCounter).Get() 38 }, 39 PostConditionFunc: func(state commands.State, result commands.Result) *gopter.PropResult { 40 if state.(int) != result.(int) { 41 return &gopter.PropResult{Status: gopter.PropFalse} 42 } 43 return &gopter.PropResult{Status: gopter.PropTrue} 44 }, 45 } 46 47 var IncBuggyCommand = &commands.ProtoCommand{ 48 Name: "INC", 49 RunFunc: func(systemUnderTest commands.SystemUnderTest) commands.Result { 50 systemUnderTest.(*BuggyCounter).Inc() 51 return nil 52 }, 53 NextStateFunc: func(state commands.State) commands.State { 54 return state.(int) + 1 55 }, 56 } 57 58 var DecBuggyCommand = &commands.ProtoCommand{ 59 Name: "DEC", 60 RunFunc: func(systemUnderTest commands.SystemUnderTest) commands.Result { 61 systemUnderTest.(*BuggyCounter).Dec() 62 return nil 63 }, 64 NextStateFunc: func(state commands.State) commands.State { 65 return state.(int) - 1 66 }, 67 } 68 69 var ResetBuggyCommand = &commands.ProtoCommand{ 70 Name: "RESET", 71 RunFunc: func(systemUnderTest commands.SystemUnderTest) commands.Result { 72 systemUnderTest.(*BuggyCounter).Reset() 73 return nil 74 }, 75 NextStateFunc: func(state commands.State) commands.State { 76 return 0 77 }, 78 } 79 80 var buggyCounterCommands = &commands.ProtoCommands{ 81 NewSystemUnderTestFunc: func(initialState commands.State) commands.SystemUnderTest { 82 return &BuggyCounter{} 83 }, 84 InitialStateGen: gen.Const(0), 85 InitialPreConditionFunc: func(state commands.State) bool { 86 return state.(int) == 0 87 }, 88 GenCommandFunc: func(state commands.State) gopter.Gen { 89 return gen.OneConstOf(GetBuggyCommand, IncBuggyCommand, DecBuggyCommand, ResetBuggyCommand) 90 }, 91 } 92 93 // Demonstrates the usage of the commands package to find a bug in a counter 94 // implementation that only occurs if the counter is above 3. 95 // 96 // The output of this example will be 97 // ! buggy counter: Falsified after 45 passed tests. 98 // ARG_0: initial=0 sequential=[INC INC INC INC DEC GET] 99 // ARG_0_ORIGINAL (9 shrinks): initial=0 sequential=[DEC RESET GET GET GET 100 // RESET DEC DEC INC INC RESET RESET DEC INC RESET INC INC GET INC INC DEC 101 // DEC GET RESET INC INC DEC INC INC INC RESET RESET INC INC GET INC DEC GET 102 // DEC GET INC RESET INC INC RESET] 103 // I.e. gopter found an invalid state with a rather long sequence of arbitrary 104 // commands/function calls, and then shrank that sequence down to 105 // INC INC INC INC DEC GET 106 // which is indeed the minimal set of commands one has to perform to find the 107 // bug. 108 func Example_buggyCounter() { 109 parameters := gopter.DefaultTestParameters() 110 parameters.Rng.Seed(1234) // Just for this example to generate reproducible results 111 112 properties := gopter.NewProperties(parameters) 113 114 properties.Property("buggy counter", commands.Prop(buggyCounterCommands)) 115 116 // When using testing.T you might just use: properties.TestingRun(t) 117 properties.Run(gopter.ConsoleReporter(false)) 118 // Output: 119 // ! buggy counter: Falsified after 43 passed tests. 120 // ARG_0: initialState=0 sequential=[INC INC INC INC DEC GET] 121 // ARG_0_ORIGINAL (8 shrinks): initialState=0 sequential=[RESET GET GET GET 122 // RESET DEC DEC INC INC RESET RESET DEC INC RESET INC INC GET INC INC DEC 123 // DEC GET RESET INC INC DEC INC INC INC RESET RESET INC INC GET INC DEC GET 124 // DEC GET INC RESET INC INC] 125 }