Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Loading in …5
×

# Functional programming's relentless bug hunter claire

168 views

Published on

• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Be the first to comment

• Be the first to like this

### Functional programming's relentless bug hunter claire

1. 1. FunctionalProgrammingsRelentless Bug Hunter:ClaireAdam Bakeradam@dobetter.com
2. 2. Property Based TestingYou may have heard of this from libraries such asQuickCheck and ScalaCheckClaire is a library by Quildreen Motta that helps you testinvariants in your javascript
3. 3. Invariants!We are used to writing tests like this:eπi = -1We should start writing tests like this:∀x. exi = cos(x) + i sin(x)
4. 4. Invariants!An old idea in computer sciencePreconditions and PostconditionsLoop InvariantsUsually expressed in a functional language
5. 5. The Strategy1. Define generators2. Identify invariants3. Convert to Claire property4. Test property on generated data5. ...6. No more bugs!
6. 6. Generators, Properties,Testsvar claire = require(claire)var _ = claire.data//two generators, Int and Numvar commutativity = claire.forAll(_.Int, _.Num).satisfy(function(integer, real){ //the property being testedreturn integer+real === real+integer}).asTest() //returns a function//use it in mochadescribe(addition, function(){it(is commutative, commutativity)})//or invoke it to see the resultscommutativity() //passes silently
7. 7. Diagnosing Propertiesvar sorted_p = forAll( _.Array(_.Int) ).satisfy(function(xs) {xs = sorted(xs)return xs.every(function(a, i) {return i == 0 || a >= xs[i - 1]})}).classify(function(xs) {return xs.length == 0 || xs.length == 1? trivial : > 1}).asTest({verbose: true, times: 1000})()// + OK passed 1000 tests.// > Collected test data:// o 98% - > 1// o 2% - trivial
8. 8. A Simple ExampleFrom a real appTo the command line!
9. 9. Generators from a morecomplex examplefunction modelObjGen(className, attrGens) {return claire.label(className)(function() {var attr, attrs, gen;attrs = {};for (attr in attrGens) {gen = attrGens[attr];attrs[attr] = gen.next().value;}return new App.Models[className](attrs);});};
10. 10. Generators from a morecomplex examplevar SpecialItem = classObjGen(SpecialItem, {type: claire.choice(Feedback, ContactForm, Document),info: gens.resize(5, ObjectGen(Any))});var Video = classObjGen(Video, {youTubeId: claire.frequency([1, Nothing], [9, Id])});var Item = claire.label(Item, claire.choice(SpecialItem, Video));var Unit = classObjGen(Unit, {items: gens.resize(6, ArrayGen(Item))});
11. 11. Properties of Addition andMultiplicationassociativity: (a+b)+c = a+(b+c)commutativity: a+b = b+aidentity: a+0 = aclosure: ∀ a,b ∈ ℤ. (a+b) ∈ ℤTest with Int, Num, and BigIntfor both addition and multiplicationWhich ones fail?
12. 12. Properties of Addition andMultiplicationTwo failures:Num fails associativity of multiplicationBigInt fails associativity of additionThe Point: Claire makes it easy to test boundary conditionsand find corner cases.
13. 13. A Look InsideSome basic generators:char = String.from-char-code### -- Primitive data types --------------------------------------------Null = as-generator nullUndefined = as-generator voidBool = choice true, falseNum = label num ((s) -> choose -s, s)Byte = label byte ((_) -> to-integer (choose 0, 255))Char = label char (transform char, Byte)Str = label str (transform join, (repeat Char))
14. 14. Container Type Generators### -- Container data types -------------------------------List = (...as) -> repeat (choice ...as)Map = (...as) -> transform to-object, (repeat (sequence Id, (choice ...as)))#### λ to-object# :internal:# Folds a list of pairs into an object.## :: [String, a] -> { String -> a }to-object = (as) -> as.reduce ((r, [k,v]) -> r <<< { "#k": v }), {}
15. 15. For the FP geeksClaires generators are monads:claire.transformacts as fmap.thenmethod on generators acts as monadic bind
16. 16. Whats in the Future?1. Shrinking of counterexamples.2. Generators based on generic lazy linked lists3. Asynchronous tests
17. 17. Why is this important?Automated teting is important.XUnit testing automates test running.Propery based testing automates test generation.Shrinking will help automate the first step in debugging.Your confidence grows each time you run your test suite.Random data (often) finds corners better than I do.
18. 18. Thanksinstall:npm install clairegithub:a talk on QuickCheck by John Hughes.https://github.com/killdream/claireFunctional Programming: A Secret Weapon for SoftwareTesting