The whAt When & how's of

unit testing

The What



A unit test is code that executes part of your
production code with an expectation on the result

- Christian Johansen


Focusing on one element of the software at a time
- hence the term unit testing

- Martin Fowler

The Why





Testability is an inherent quality of good design
- C. Johansen

The why


TEST TO

FACILITATE CHANGE


TEST For

CONSISTENCY / REGRESSION

MAINTAINABLE CODE

DOCUMENTATION

THE why




Like they say in the circus

DON'T WORK WITHOUT A NET!

THE HOW


1. Take the smallest piece of testable software

2. Isolate it from the remainder of the code

3. Make sure it behaves as you expect 


Found a bug?
Write a test
Fix the bug


TDD

Test Driven Development


Because your'e worth it!


Red

Green

Refactor


Uncle Bob's three laws

first law



You may not write production code 

until you have written

a failing Unit test

Second LAW



YOU MAY NOT WRITE More

of a Unit test

Than is sufficient to fail

(not compiling=failing)

Third LAW



YOU MAY NOT WRITE more

PRODUCTION CODE

than is sufficient

to pass the failing test


REGULAR EXPRESSIONS



\b((25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\b

IPv4 address


\bM{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b

Roman numerals



how?


  describe("isIpv4()", function() { it("should ...", function(){  }); });





Transforming DATA

TRANSFORMING DATA


{ data: { fsrf: false, versions: {
"0": { variableInfo: { header: "Foo", executions: [ {id: 1, code: "F0103A"}, {id: 2, code: "F0105C"}, {id: 3, code: null}], imageUrls: ["http://example.com/img/763498087376276l.jpg"]}}}}};

 {    title: "Foo",    executions: ["F0103A", "F0105C"],    imgUrl: "http://example.com/img/763498087376276.jpg" }



How?


describe("#transformData", function(){ it("should ...", function(){}); });





Async code

ASYNC CODE



           setTimeout(function() { return "value"; }, 500);


                   App.Module.find = function() {  };

HOW?



done (mocha)

spy (sinon)

eventually (chai-as-promised)



cometh



SINON.JS

SPIES, STUBS & MOCKS

SpIES


Record calls and arguments

Proxy original method


var spy = sinon.spy(); 
var spy = sinon.spy(function);
var spy = sinon.spy(object, "method");
spy.getCall(0).args[0];spy.called[Count|Once|Twice|Thrice] // true|falsespy.calledWith();

Stubs Spies++



SPIES with pre-programmed behavior

Does not proxy the original method


 var ajax = sinon.stub(jQuery, 'ajax');

stub.return[s]
stub.throw[s]
stub.yield[s]

MockS StubS++


Stubs with pre-programmed expectations



testa mot returvärde vs göra ngt



mock.verify()

Rolling your own


sinon.promise = function() {  var promise = {    then: sinon.stub(),    done: sinon.stub(),    fail: sinon.stub(),    always: sinon.stub()  };
promise.then.returns(promise);
promise.done.returns(promise); promise.fail.returns(promise); promise.always.returns(promise);
return promise;};


If a test case won't fail

by it's own -

it's probably not useful



Don't test 2 much!

it's impossible to test everything



When tests drive development

you end up with enough test



Write tests

that force you to write production code

that solves the problem

nothing more



Refactor testcode & go to developer nirvana



USE CODE COVERAGE


TO ANALYSE


AND DESTROY



Good tests === good coverage



Good coverage  !== good tests



A tests-last trap

PRACTICE





READ ON




http://cjohansen.no/talks/2011/xp-meetup/ 


http://martinfowler.com/articles/asyncJS.html





expect("presentation").to.be.complete();



THE END

Unit testing in JavaScript

By Pontus Lundin

Unit testing in JavaScript

The What WHEN & HOW'S OF unit testing

  • 879