Test Driven Development with JavaScript

Andrii Kucherenko

TDD steps

  • Navigation map

  • Test first

  • Assert first

  • Fail first

  • Continious integration

Test first

describe('Calculator', 
    function () {
        it('should summarize two numbers', 
            function () {
        
            }
        );
    }
);

Assert first

describe('Calculator', function () {

    it('should summarize two numbers', 
        function () {
            sut.sum(1, 2).should.equal(3);
        }
    );

});

Fail first

> mocha test/*.spec.js


  ․

  0 passing (4ms)
  1 failing

  1) String Calculator "before each" hook:
     ReferenceError: Calculator is not defined
      at Context.<anonymous> (/home/apk/workspace/lab/tdd/test/Calculator.spec.js:5:15)
      at callFn (/home/apk/workspace/lab/tdd/node_modules/mocha/lib/runnable.js:223:21)
      at Hook.Runnable.run (/home/apk/workspace/lab/tdd/node_modules/mocha/lib/runnable.js:216:7)
      at next (/home/apk/workspace/lab/tdd/node_modules/mocha/lib/runner.js:258:10)
      at Object._onImmediate (/home/apk/workspace/lab/tdd/node_modules/mocha/lib/runner.js:275:5)
      at processImmediate [as _immediateCallback] (timers.js:330:15)

Benefits

  • Unit tests coverage

  • Increases assurance of correctness

  • More complete explorations of requirements

  • Improved code

  • Code as documentation

  • Safe refactoring

  • No extra code

Baby steps 

Pair programming

Emergent Design

Continious integration

Tools

Test’em!

grunt-mutation-testing

coverage-blamer

it("calls the original function", function () {
    var callback = sinon.spy();
    var proxy = once(callback);

    proxy();

    assert(callback.called);
});


it("returns the return value from the original function", function () {
    var callback = sinon.stub().returns(42);
    var proxy = once(callback);

    assert.equals(proxy(), 42);
});


it("returns the return value from the original function", function () {
    var myAPI = { method: function () {} };
    var mock = sinon.mock(myAPI);
    mock.expects("method").once().returns(42);

    var proxy = once(myAPI.method);

    assert.equals(proxy(), 42);
    mock.verify();
});

JSCoverage

Istanbul

grunt-mutation-testing

Books

Questions?

Thank you!