Abhishek Yadav
@h6165
# Example of examples
def add(a, b)
a + b
end
# Test examples -
expect(add(1,2)).to eq(3)
expect(add(0,0)).to eq(0)
expect(add(-1,1)).to eq(0)
# and so on...
That seems ok
# Pythagoras
def hypotenuse(a, b)
Math.sqrt(a**2 + b**2)
end
# Test examples -
expect(hypotenuse(3, 4)).to eq(5.0)
expect(hypotenuse(5, 7)).to eq(8.6)
expect(hypotenuse(0, 0)).to eq(0)
expect(hypotenuse(-1, -2))
.to raise_error
# and so on...
Here,
we desperately feel the urge to express the Pythagoras theorem
To say, that the square of the hypotenuse equals the sum of the squares of the sides
That, is a property
# Pythagoras
def hypotenuse(a, b)
Math.sqrt(a**2 + b**2)
end
# What we need -
for_all_possible_values {
h = hypotenuse(a,b)
expect(h**2).to eq(a**2 + b**2)
}
The square of the hypotenuse equals the sum of the squares of the sides
Haskells Quickcheck
Ruby's Quickcheck
rubycheck - a direct port
https://github.com/mcandre/rubycheck
theft -
https://rubygems.org/gems/theftrantly
https://github.com/rantly-rb/rantly
Ruby's Rantly
# Pythagoras
# Property Test -
it 'hypotenuse squared is sum of sides squared' do
property_of {
a = integer
b = integer
[a, b]
}
.check(200) { |a, b|
h2 = a**2 + b**2
h2x = hypotenuse(a, b) ** 2
expect(h2x).to eq(h2)
}
end
Ruby's Rantly
property_of {
a = integer
b = integer
[a, b]
}
Generate random test data
.check(200) { |a, b|
h2 = a**2 + b**2
h2x = hypotenuse(a, b) ** 2
expect(h2x).to eq(h2)
}
Verify our function using the test data
(with 200 different data points)
Ruby's Rantly
.check(200) { |a, b|
h2 = a**2 + b**2
h2x = hypotenuse(a, b) ** 2
expect(h2x).to eq(h2)
}
Does that feel a bit wrong ?
We've almost specified the implementation here
Is that acceptable ?
Why or why not ?
Ruby's Rantly
Demo
Conclusion - Example tests vs Property tests
Conclusion - Example tests vs Property tests
That's all