51
T O f R b W r Joseph Wilk

Testing outside of the Ruby World

Embed Size (px)

Citation preview

Page 1: Testing outside of the Ruby World

T!"#$%& O'#"$(! )f #*!

R'b+ W)r,(Joseph Wilk

Page 2: Testing outside of the Ruby World

Wait isn’t this a Ruby conference?

Page 3: Testing outside of the Ruby World

Seriously...

No Ruby tools.

Really.

Page 4: Testing outside of the Ruby World

Science

“The number of languages you know corresponds to your programming

skill”

Page 5: Testing outside of the Ruby World

JUnit

Rspec

PHPSpec

JSpec

Circumspec

SomethingSpec

Yay... TestingScrewUnit

JBehave

Jasmine

Cucumber

BlahSpec

WhateverSpec

Page 6: Testing outside of the Ruby World

JUnit

Rspec

PHPSpec

JSpec

Circumspec

SomethingSpec

Yay... TestingScrewUnit

JBehave

Jasmine

Cucumber

BlahSpec

WhateverSpec

BORING!

Page 7: Testing outside of the Ruby World

T.ing & Mocking

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.

Page 8: Testing outside of the Ruby World

T.ing & Mocking

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!

Page 9: Testing outside of the Ruby World

InterestingAsynchronous Property testing

Model testingPermutation explosions

Test feedbackMetrics

Graphical tests

Page 10: Testing outside of the Ruby World

HaskellCurry

Page 11: Testing outside of the Ruby World

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

Edsger Dijkstra

Page 12: Testing outside of the Ruby World

QuickCheckProperties

∀s . length(five_random_characters(s)) = 5

For all values of s the length of the thing returned by five_random_characters is 5

Page 13: Testing outside of the Ruby World

QuickCheck

LogicRandomly generate

testsFunctionFunction

Properties

QuickCheck

Page 14: Testing outside of the Ruby World

QuickCheck

LogicRandomly generate

testsFunctionFunction

Properties

QuickCheck

Page 15: Testing outside of the Ruby World

QuickCheck

LogicRandomly generate

testsFunctionFunction

Properties

QuickCheck

Page 16: Testing outside of the Ruby World

QuickCheck

LogicRandomly generate

testsFunction

Properties

QuickCheck

Page 17: Testing outside of the Ruby World

QuickCheck

LogicRandomly generate

testsFunction

Properties

QuickCheck

Counter Examples

Page 18: Testing outside of the Ruby World

QuickCheckProperties

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 endend

Page 19: Testing outside of the Ruby World

QuickCheckimport Data.Charimport 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_RevRevOK, passed 100 tests.

Page 20: Testing outside of the Ruby World

ErlangMessaging/

Concurrency

Page 21: Testing outside of the Ruby World

Erlang runtimesystem

McErlang runtimesystem

McErlangModels

communication

concurrency

distribution

Page 22: Testing outside of the Ruby World

McErlangModels

MessengerService

Message client

Message client

Fred Clara

message“Scottish fiction”

“Scottish fiction”

login login

Page 23: Testing outside of the Ruby World

McErlangif 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 fredQ: fred is logged onR: fred receives the message “Scottish fiction” from clara

Models

Page 24: Testing outside of the Ruby World

McErlangModels

{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}}).

Page 25: Testing outside of the Ruby World

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

Pesticide Paradox / Beizer

Page 26: Testing outside of the Ruby World

ClojureBracket

hell

Page 27: Testing outside of the Ruby World

(fact (alive-in-next-generation? ...cell...) => truthy   (provided     (alive? ...cell...) => false    (neighbor-count ...cell...) => 3))

MidjeFacts

cell = mock("a cell")cell.stub(:alive?).and_return(false)cell.stub(:neighbour_count).and_return(3)

cell.alive_in_next_generation.should == true

Page 28: Testing outside of the Ruby World

IokeBrief visit

Page 29: Testing outside of the Ruby World

IokeSpecs are documentation

Page 30: Testing outside of the Ruby World

IokeSpecs are documentation

Page 31: Testing outside of the Ruby World

JavaScriptWithout the Java

Page 32: Testing outside of the Ruby World

Zombie.jsTrapped inside a browser

Page 33: Testing outside of the Ruby World

Zombie.jsTrapped 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"); })});

Page 34: Testing outside of the Ruby World

VowsTopics

{ topic: function () { return 42 },

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

Page 35: Testing outside of the Ruby World

VowsAsynchronous 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 }}

Page 36: Testing outside of the Ruby World

VowsPromises / 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 }}

Page 37: Testing outside of the Ruby World

VowsParallel 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) } }}

Page 38: Testing outside of the Ruby World

Permutation ExplosionTestSwarm

Page 39: Testing outside of the Ruby World

Permutation ExplosionTestSwarm

Page 40: Testing outside of the Ruby World

JavaReally

Page 41: Testing outside of the Ruby World

JunitM3Faster Test feedback

Lots of very short testsA few very long ones

Failures are not randomly distributed

Kent Beck

Page 42: Testing outside of the Ruby World

JunitM3Faster Test feedback

Page 43: Testing outside of the Ruby World

Industrial LogicLearn from Metrics

Page 44: Testing outside of the Ruby World

Other stuffdessert

Page 45: Testing outside of the Ruby World

‘‘What is the use of a book,’’ thought Alice, ‘‘without pictures or conversations?’’

Lewis Carroll Alice’s Adventures in Wonderland

Page 46: Testing outside of the Ruby World

Swim LaneWords are not enough

Ward Cunningham

Page 47: Testing outside of the Ruby World

Ward Cunningham

http://vimeo.com/22165070

Page 48: Testing outside of the Ruby World

Graphical Testing

Brian Marick

Page 49: Testing outside of the Ruby World

http://testobsessed.com/wp-content/uploads/2007/02/testheuristicscheatsheetv1.pdf

‘‘How much do you know about the heuristics of failure?’

Joseph WilkScotland Ruby Conf 2011

Page 50: Testing outside of the Ruby World

Tasty Ideas

Page 51: Testing outside of the Ruby World

5anks!Joseph Wilk

@josephwilkhttp://blog.josephwilk.net