Test Driven Development with JavaScript

Andrey Kucherenko

TDD steps

  • Navigation map

  • Test first

  • Assert first

  • Fail first

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

Emergent Design

Tools

grunt-mutation-testing

coverage-blamer

chai.should();

beforeEach(function() {
    window.env = sinon.sandbox.create();
});

afterEach(function() {
    window.env.restore();
});

test_config.js

it("calls the original function", function () {
    // env - global sinon sandbox
    var callback = env.spy();
    var proxy = once(callback);

    proxy();

    assert(callback.called);
});


it("returns the return value from the original function", function () {
    var callback = env.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 = env.mock(myAPI);
    mock.expects("method").once().returns(42);

    var proxy = once(myAPI.method);

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

JSCoverage

Istanbul

isparta

remap-istanbul

istanbul-combine

grunt-mutation-testing

coverage-blamer

Books

Questions?

Thank you!

TDD for Javascript

By Andrey Kucherenko

TDD for Javascript

Bitary Studio MeetUp

  • 1,915