Slide 1

Slide 1 text

T O f R b W r Joseph Wilk

Slide 2

Slide 2 text

W ’ R b f r ?

Slide 3

Slide 3 text

S r ... N R b . R .

Slide 4

Slide 4 text

S “The number of languages you know corresponds to your programming skill”

Slide 5

Slide 5 text

JUnit Rspec PHPSpec JSpec Circumspec SomethingSpec Y ... T ScrewUnit JBehave Jasmine Cucumber BlahSpec WhateverSpec

Slide 6

Slide 6 text

JUnit Rspec PHPSpec JSpec Circumspec SomethingSpec Y ... T ScrewUnit JBehave Jasmine Cucumber BlahSpec WhateverSpec BORING!

Slide 7

Slide 7 text

T & M Java Ruby Monkey.stub!(:new).and_return(mock("monkey")) I owe you one Java mocking example. I don’t have the will power to write it. Sorry.

Slide 8

Slide 8 text

T & M Java Ruby Monkey.stub!(:new).and_return(mock("monkey")) I owe you one Java mocking example. I don’t have the will power to write it. Sorry. BORING!

Slide 9

Slide 9 text

I r Asynchronous Property testing Model testing Permutation explosions Test feedback Metrics Graphical tests

Slide 10

Slide 10 text

H Curry

Slide 11

Slide 11 text

“Program testing can be used to show the presence of bugs, but never to show their absence!” Edsger Dijkstra

Slide 12

Slide 12 text

Q C Properties ˲TMFOHUI GJWF@SBOEPN@DIBSBDUFST T  For all values of s the length of the thing returned by five_random_characters is 5

Slide 13

Slide 13 text

Q C Logic Randomly generate tests Function Function Properties QuickCheck

Slide 14

Slide 14 text

Q C Logic Randomly generate tests Function Function Properties QuickCheck

Slide 15

Slide 15 text

Q C Logic Randomly generate tests Function Function Properties QuickCheck

Slide 16

Slide 16 text

Q C Logic Randomly generate tests Function Properties QuickCheck

Slide 17

Slide 17 text

Q C Logic Randomly generate tests Function Properties QuickCheck Counter Examples

Slide 18

Slide 18 text

Q C Properties it "should reverse a string" do "monkeys".reverse.reverse.should == "monkeys" end 100.times.map {“#{rand(10)}#{rand(10)}”}.each do |char| it "should reverse a string" do char.reverse.reverse.should == char end end

Slide 19

Slide 19 text

Q C import Data.Char import Test.QuickCheck instance Arbitrary Char where arbitrary = choose ('\32', '\128') coarbitrary c = variant (ord c `rem` 4) prop_RevRev xs = reverse (reverse xs) == xs where types = xs::[Char] Properties $ Main> quickCheck prop_RevRev OK, passed 100 tests.

Slide 20

Slide 20 text

Er Messaging/ Concurrency

Slide 21

Slide 21 text

Erlang runtime system McErlang runtime system M Er Models communication concurrency distribution

Slide 22

Slide 22 text

M Er Models Messenger Service Message client Message client Fred Clara message “Scottish fiction” “Scottish fiction” login login

Slide 23

Slide 23 text

M Er if user1 does not send a message m to user2 until user2 is logged on, then if user1 does send a message m to user2 then eventually user2 receives the message m. "not P until Q => (eventually P => eventually R)” P: clara sends message “Scottish fiction” to fred Q: fred is logged on R: fred receives the message “Scottish fiction” from clara Models

Slide 24

Slide 24 text

M Er Models {program={scenario,start,[[ [{logon,clara},{message,fred,"hi"},logoff], [{logon,fred},logoff]]]}, monitor={mce_ltl_parse:ltl_string2module_and_load ("not P until Q implies (eventually P implies eventually R)", messenger_mon), {void,[{'P',basicPredicates:message_to (clara,fred,"hi")}, {'Q',basicPredicates:logon(fred)}, {'R',basicPredicates:message_received (fred,clara,"hi")}]}}, algorithm={mce_alg_buechi,void}}).

Slide 25

Slide 25 text

“Every method you use to prevent or find bugs leaves a residue of subtler bugs against which those methods are ineffectual Pesticide Paradox / Beizer

Slide 26

Slide 26 text

C r Bracket hell

Slide 27

Slide 27 text

(fact (alive-in-next-generation? ...cell...) => truthy (provided (alive? ...cell...) => false (neighbor-count ...cell...) => 3)) M Facts cell = mock("a cell") cell.stub(:alive?).and_return(false) cell.stub(:neighbour_count).and_return(3) cell.alive_in_next_generation.should == true

Slide 28

Slide 28 text

I Brief visit

Slide 29

Slide 29 text

I Specs are documentation

Slide 30

Slide 30 text

I Specs are documentation

Slide 31

Slide 31 text

J v S r p Without the Java

Slide 32

Slide 32 text

Z b . Trapped inside a browser

Slide 33

Slide 33 text

Z b . Trapped inside a browser var zombie = require("zombie"); var assert = require("assert"); zombie.visit("http://localhost:3000/", function (err, browser, status) { browser. fill("email", "[email protected]"). pressButton("Sign Me Up!", function(err, browser, status) { assert.equal(browser.text("title"), "Welcome"); }) });

Slide 34

Slide 34 text

V w Topics { topic: function () { return 42 }, 'should be a number': function (topic) { assert.isNumber (topic); }, 'should be equal to 42': function (topic) { assert.equal (topic, 42); } }

Slide 35

Slide 35 text

V w Asynchronous calls { topic: function () { fs.stat('~/FILE', this.callback); }, 'can be accessed': function (err, stat) { assert.isNull (err); // We have no error assert.isObject (stat); // We have a stat object }, 'is not empty': function (err, stat) { assert.isNotZero (stat.size); // The file size is > 0 } }

Slide 36

Slide 36 text

V w Promises / Futures { topic: function () { var promise = new(events.EventEmitter); fs.stat('~/FILE', function (e, res) { if (e) { promise.emit('error', e) } else { promise.emit('success', res) } }); return promise; }, 'can be accessed': function (err, stat) { assert.isNull (err); //We have no error assert.isObject (stat); //We have a stat object }, 'is not empty': function (err, stat) { assert.isNotZero (stat.size); //The file size is > 0 } }

Slide 37

Slide 37 text

V w Parallel Execution { '/dev/stdout': { topic: function () { path.exists('/dev/stdout',this.callback) }, 'exists': function (result) { assert.isTrue(result) } }, '/dev/tty': { topic: function () { path.exists('/dev/tty',this.callback) }, 'exists': function (result) { assert.isTrue(result) } }, '/dev/null': { topic: function () { path.exists('/dev/null',this.callback) }, 'exists': function (result) { assert.isTrue(result) } } }

Slide 38

Slide 38 text

Permutation Explosion T Sw r

Slide 39

Slide 39 text

Permutation Explosion T Sw r

Slide 40

Slide 40 text

J v Really

Slide 41

Slide 41 text

J M Faster Test feedback Lots of very short tests A few very long ones Failures are not randomly distributed Kent Beck

Slide 42

Slide 42 text

J M Faster Test feedback

Slide 43

Slide 43 text

I r L Learn from Metrics

Slide 44

Slide 44 text

O r ff dessert

Slide 45

Slide 45 text

‘‘What is the use of a book,’’ thought Alice, ‘‘without pictures or conversations?’’ Lewis Carroll Alice’s Adventures in Wonderland

Slide 46

Slide 46 text

Sw L Words are not enough Ward Cunningham

Slide 47

Slide 47 text

Ward Cunningham http://vimeo.com/22165070

Slide 48

Slide 48 text

Gr p T Brian Marick

Slide 49

Slide 49 text

http://testobsessed.com/wp-content/uploads/2007/02/testheuristicscheatsheetv1.pdf ‘‘How much do you know about the heuristics of failure?’ Joseph Wilk Scotland Ruby Conf 2011

Slide 50

Slide 50 text

T I

Slide 51

Slide 51 text

! Joseph Wilk @josephwilk http://blog.josephwilk.net