A Taste of Mocha












@eschoff - @funkytek - @wearefractal

Consulting, training, products, professional services

contact@wearefractal.com

Open source is at github.com/wearefractal






Terminology













TDD


Test Driven Development


  • Write tests before any code is written
  • Traditionall uses X-Unit

"Make sure the code works"


ATDD


Acceptance Test Driven Development


  • Should be readable by the business guys
  • Team driven

"Make sure the features are correct"


BDD


Behaviour Driven Development


  • Extends TDD
  • Uses ATDD
  • Team driven

"Should, given, when, then"






Test. Relax.
















Wouldn't it be nice to be confident about what you have in production?
Wouldn't it be nice to guarantee your code works and have the tests to prove it?


Tested code is good code.

Give yourself peace of mind and just test.





Mocha


simple, flexible, fun










Features


  • Browser support
  • Async support
  • Code coverage tools
  • Extensible DSLs
  • Interfaces to suit your style (BDD by default)
  • Hooks for pre and post processing
  • Diffs for reporting

Diffs

Simplicity


Your test is a simple function that takes a callback.

You do your checks and balances within the function.

You call the callback when you are done.

function test(done){
  assert.equal(1, 1);
  done();
}

Simple right?
You can also pass errors to done() to make things easier

BDD Interface


var assert = require("assert");
describe('Array', function(){
  describe('#indexOf()', function(){
    it('should return -1 when the value is not present', function(done){
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
      done();
    });
  });
});
  • Categorize your tests with 'describe'
  • These can be nested as deep as you want
  • Describe a specific test with 'it'

TDD Interface


var assert = require("assert");
suite('Array', function(){
  suite('#indexOf()', function(){
    test('should return -1 when not present', function(done){
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
      done();
    });
  });
});
  • Categorize your tests with 'suite'
  • These can be nested as deep as you want
  • Describe a specific test with 'test'

Exports Interface


var assert = require("assert");

module.exports = {
  'Array': {
    '#indexOf()': {
      'should return -1 when not present': function(done){
        assert.equal(-1, [1,2,3].indexOf(5));
        assert.equal(-1, [1,2,3].indexOf(0));
        done();
      }
    }
  }
};
  • Categorize your tests by wrapping it in an object
  • These can be nested as deep as you want
  • Describe a specific test or category with object key







Reporters











Spec Reporter

Dot Matrix Reporter

Nyan Cat Reporter

Hooks


before and after = one test
beforeEach and afterEach = every test

You can nest these as deep as you want.

The names change between interfaces but are all the same.

Hooks (BDD)


describe('Connection', function(){
  var db = new Connection();
  var tobi = new User('tobi');
  
  // wipe the databse
  beforeEach(db.clear);
  
  // seed the database with fake data
  beforeEach(function(done){
    db.save(tobi, done);
  });

  describe('#find()', function(){
    it('should respond with matching records', function(done){
      db.find({ type: 'User' }, function(err, res){
        if (err) return done(err);
        assert.equal(res.length, 1);
        done();
      });
    });
  });
});








Let's Test











Installation


npm install -g mochagit clone https://github.com/wearefractal/mocha-adventurecd mocha-adventure

Add/Substract


cd test/add
mocha .
cd test/subtract
mocha .
Add the missing code to match the test

Mult/Divide


cd test/multiply
mocha .
cd test/divide
mocha .
Add the missing test to match the code

Calc - Finish


mocha .
Add the missing test for all functions
Made with Slides.com