Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n|...
Transcript of Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n|...
![Page 1: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/1.jpg)
Property-Based Testing
![Page 2: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/2.jpg)
Kinds of Testing
![Page 3: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/3.jpg)
Example-Based Tests
![Page 4: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/4.jpg)
+, -‐
![Page 5: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/5.jpg)
expect(1 + 2).to eq 3
![Page 6: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/6.jpg)
expect(3 -‐ 2).to eq 1
![Page 7: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/7.jpg)
expect(3 -‐ 2).to eq 1
![Page 8: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/8.jpg)
Property-Based Tests
![Page 9: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/9.jpg)
For some number, n: !
n + 1 > n
![Page 10: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/10.jpg)
For some number, n: !
n + 1 > n n -‐ 1 < n
![Page 11: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/11.jpg)
For some number, n: !
n + 1 > n n -‐ 1 < n
n + 1 -‐ 1 = n #
![Page 12: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/12.jpg)
Practicalities
![Page 13: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/13.jpg)
it "describes + and -‐" do property_of { integer }.check { |n| expect(n + 1 > n).to be true expect(n -‐ 1 < n).to be true expect(n + 1 -‐ 1).to eq n } end
![Page 14: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/14.jpg)
it "describes + and -‐" do property_of { integer }.check { |n| expect(n + 1 > n).to be true expect(n -‐ 1 < n).to be true expect(n + 1 -‐ 1).to eq n } end
![Page 15: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/15.jpg)
it "describes + and -‐" do property_of { integer }.check { |n| expect(n + 1 > n).to be true expect(n -‐ 1 < n).to be true expect(n + 1 -‐ 1).to eq n } end
![Page 16: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/16.jpg)
it "describes + and -‐" do property_of { integer }.check { |n| expect(n + 1 > n).to be true expect(n -‐ 1 < n).to be true expect(n + 1 -‐ 1).to eq n } end
![Page 17: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/17.jpg)
success: 100 tests describes + and -‐
![Page 18: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/18.jpg)
Something that breaks
![Page 19: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/19.jpg)
For some string, x: !
x.split(" ").join(" ") == x
![Page 20: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/20.jpg)
it "split/join is reversible" do property_of { string }.check { |x| expect( x.split(" ").join(" ") ).to eq(x) } end
![Page 21: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/21.jpg)
it "split/join is reversible" do property_of { string }.check { |x| expect( x.split(" ").join(" ") ).to eq(x) } end
![Page 22: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/22.jpg)
it "split/join is reversible" do property_of { string }.check { |x| expect( x.split(" ").join(" ") ).to eq(x) } end
![Page 23: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/23.jpg)
it "split/join is reversible" do property_of { string }.check { |x| expect( x.split(" ").join(" ") ).to eq(x) } end
![Page 24: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/24.jpg)
failure after 7 tests, on: " &2M1`" found a reduced failure case: " &M1`" found a reduced failure case: " M1`" found a reduced success: "M1`" minimal failed data is: " M1`" split/join is reversible (FAILED -‐ 1)
![Page 25: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/25.jpg)
failure after 7 tests, on: " &2M1`" found a reduced failure case: " &M1`" found a reduced failure case: " M1`" found a reduced success: "M1`" minimal failed data is: " M1`" split/join is reversible (FAILED -‐ 1)
![Page 26: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/26.jpg)
failure after 7 tests, on: " &2M1`" found a reduced failure case: " &M1`" found a reduced failure case: " M1`" found a reduced success: "M1`" minimal failed data is: " M1`" split/join is reversible (FAILED -‐ 1)
![Page 27: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/27.jpg)
failure after 7 tests, on: " &2M1`" found a reduced failure case: " &M1`" found a reduced failure case: " M1`" found a reduced success: "M1`" minimal failed data is: " M1`" split/join is reversible (FAILED -‐ 1)
![Page 28: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/28.jpg)
failure after 7 tests, on: " &2M1`" found a reduced failure case: " &M1`" found a reduced failure case: " M1`" found a reduced success: "M1`" minimal failed data is: " M1`" split/join is reversible (FAILED -‐ 1)
![Page 29: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/29.jpg)
Three Things: Data Generation,
Testing with the Data, Data Reduction
![Page 30: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/30.jpg)
Uses
![Page 31: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/31.jpg)
Edge Cases
![Page 32: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/32.jpg)
Treating the code like an adversary
![Page 33: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/33.jpg)
Honest TDD;No fudging code to
pass an example test.
![Page 34: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/34.jpg)
Kinds of Properties
![Page 35: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/35.jpg)
Reversible
![Page 36: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/36.jpg)
n + 1 -‐ 1 == n
Reversible
![Page 37: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/37.jpg)
n + 1 -‐ 1 == n !
# where y != " "x.split(y).join(y) == x
Reversible
![Page 38: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/38.jpg)
n + 1 -‐ 1 == n !
# where y != " "x.split(y).join(y) == x
!
decompress(compress(d)) == d
Reversible
![Page 39: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/39.jpg)
n + 1 -‐ 1 == n !
# where y != " "x.split(y).join(y) == x
!
decompress(compress(d)) == d !
t.to_zone('UTC') .to_zone(t.zone) == t.zone
Reversible
![Page 40: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/40.jpg)
n + 1 -‐ 1 == n !
# where y != " "x.split(y).join(y) == x
!
decompress(compress(d)) == d !
t.to_zone('UTC') .to_zone(t.zone) == t.zone
Reversible
I goofed this in the original; I've fixed this example. Pardon my onstage embarrassment. :-)
![Page 41: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/41.jpg)
Repeatable
![Page 42: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/42.jpg)
list.sort.sort == list.sortRepeatable
![Page 43: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/43.jpg)
list.sort.sort == list.sort !
handler.handle(evt).handle(evt) == handler.handle(evt)
Repeatable
![Page 44: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/44.jpg)
Unbreakable Rules
![Page 45: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/45.jpg)
list.sort.count == list.count
Unbreakable Rules
![Page 46: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/46.jpg)
list.sort.count == list.count !
list.sort.all? {|x| list.find_index(x) != nil }
Unbreakable Rules
![Page 47: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/47.jpg)
Swapping the Ordering
![Page 48: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/48.jpg)
a.map{|n| n + 1}.sort ==
a.sort.map{|n| n + 1}
Swapping the Ordering
![Page 49: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/49.jpg)
Prove a Small Part
![Page 50: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/50.jpg)
pairs(list.sort).all?{|(x,y)| x <= y } # pairs([1,2,3]) # => [[1,2], [2,3]]
Prove a Small Part
![Page 51: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/51.jpg)
Hard to Solve, Easy to Check
![Page 52: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/52.jpg)
solve(solvable_maze) != nil solve(unsolvable_maze) == nil
Hard to Solve, Easy to Check
![Page 53: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/53.jpg)
solve(solvable_maze) != nil solve(unsolvable_maze) == nil
Hard to Solve, Easy to Check
I really punted on this example, particularly how you generate a maze you know is solvable. Sorry.
![Page 54: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/54.jpg)
Consult an Oracle
![Page 55: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/55.jpg)
list.hypersort == list.sort
Consult an Oracle
![Page 56: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/56.jpg)
list.hypersort == list.sort !
new_code(input) == old_code(input)
Consult an Oracle
![Page 57: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/57.jpg)
SHOW US SOME REAL EXAMPLES
![Page 58: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/58.jpg)
it "can round-‐trip last-‐logged-‐in" do property_of { (Time.current -‐ float.abs) }.check { |time| user = User.create( username: "Sam", last_logged_in_at: time, ) expect( User.find(user.id).last_logged_in_at ).to eq(time) } end
![Page 59: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/59.jpg)
it "can round-‐trip last-‐logged-‐in" do property_of { (Time.current -‐ float.abs) }.check { |time| user = User.create( username: "Sam", last_logged_in_at: time, ) expect( User.find(user.id).last_logged_in_at ).to eq(time) } end
![Page 60: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/60.jpg)
it "can round-‐trip last-‐logged-‐in" do property_of { (Time.current -‐ float.abs) }.check { |time| user = User.create( username: "Sam", last_logged_in_at: time, ) expect( User.find(user.id).last_logged_in_at ).to eq(time) } end
![Page 61: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/61.jpg)
failure: 0 tests, on: Sat, 13 Jun 2015 04:39:52 UTC +00:00 can round-‐trip last-‐logged-‐in (FAILED -‐ 1) !Failures: ! 1) User round-‐trip can round-‐trip last-‐logged-‐in Failure/Error: expect(User.find(user.id).last_logged_in_at).to eq time ! expected: 2015-‐06-‐13 04:39:52.835645641 +0000 got: 2015-‐06-‐13 04:39:52.835645000 +0000
![Page 62: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/62.jpg)
it "after_transition args" do property_of { array { choose boolean, string, integer} }.check { |args| test = -‐> (a) { expect(a).to eq(args) } ! machine = Class.new do state_machine initial: :stopped do event :go do transition :stopped => :going end after_transition(:stopped => :going, :do => proc { |machine,transition| test.call(transition.args) }) end end ! machine.new.go(*args) } end
![Page 63: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/63.jpg)
it "after_transition args" do property_of { array { choose boolean, string, integer} }.check { |args| test = -‐> (a) { expect(a).to eq(args) } ! machine = Class.new do state_machine initial: :stopped do event :go do transition :stopped => :going end after_transition(:stopped => :going, :do => proc { |machine,transition| test.call(transition.args) }) end end ! machine.new.go(*args) } end
![Page 64: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/64.jpg)
it "after_transition args" do property_of { array { choose boolean, string, integer} }.check { |args| test = -‐> (a) { expect(a).to eq(args) } ! machine = Class.new do state_machine initial: :stopped do event :go do transition :stopped => :going end after_transition(:stopped => :going, :do => proc { |machine,transition| test.call(transition.args) }) end end ! machine.new.go(*args) } end
![Page 65: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/65.jpg)
it "after_transition args" do property_of { array { choose boolean, string, integer} }.check { |args| test = -‐> (a) { expect(a).to eq(args) } ! machine = Class.new do state_machine initial: :stopped do event :go do transition :stopped => :going end after_transition(:stopped => :going, :do => proc { |machine,transition| test.call(transition.args) }) end end ! machine.new.go(*args) } end
![Page 66: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/66.jpg)
failure: 1 tests, on: ["y}K'ID", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["y}K'D", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["}K'D", "aR/-‐xm", "^H:/_B", true, false, true] ... found a reduced failure case: ["", "", "", true, false, true] found a reduced failure case: ["", "", "", true, false] found a reduced failure case: ["", "", "", false] found a reduced success: ["", "", ""] minimal failed data is: ["", "", "", false]
![Page 67: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/67.jpg)
failure: 1 tests, on: ["y}K'ID", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["y}K'D", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["}K'D", "aR/-‐xm", "^H:/_B", true, false, true] ... found a reduced failure case: ["", "", "", true, false, true] found a reduced failure case: ["", "", "", true, false] found a reduced failure case: ["", "", "", false] found a reduced success: ["", "", ""] minimal failed data is: ["", "", "", false]
![Page 68: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/68.jpg)
failure: 1 tests, on: ["y}K'ID", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["y}K'D", "aR/-‐xm", "^H:/_B", true, false, true] found a reduced failure case: ["}K'D", "aR/-‐xm", "^H:/_B", true, false, true] ... found a reduced failure case: ["", "", "", true, false, true] found a reduced failure case: ["", "", "", true, false] found a reduced failure case: ["", "", "", false] found a reduced success: ["", "", ""] minimal failed data is: ["", "", "", false]
![Page 69: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/69.jpg)
Random vs
Exhaustive
![Page 70: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/70.jpg)
Refs, Credits and Things to Look At
• fsharpforfunandprofit.com(Property-Based Testing Posts)
• github.com/charleso/property-testing-preso (LambdaJam talk)
• Rantly (Ruby, used in examples)
• QuickCheck, SmallCheck (Haskell)
• Hypothesis (Python)
![Page 71: Property-Based Testing - robhoward.id.au · it"describes+and"do property_of{integer}.check{|n| expect(n+1>n).tobetrue expect(n1](https://reader034.fdocuments.us/reader034/viewer/2022042303/5ece2c90ee11c142a623db2e/html5/thumbnails/71.jpg)
Fin.
Rob Howard
@damncabbage robhoward.id.au