KEMBAR78
Test driven node.js
TEST

DRIVEN
What is node.js?

“

Node.js is a platform built on
Chrome's JavaScript runtime for
easily building fast, scalable network
applications.

”
basicFundamentals
packageManagement
is not an acronym
is an acronym

National Association of Pastoral Musicians
github: isaacs/npm
install: comes with node
localInstallation
npm install <package>
globalInstallation
npm install <package> --global
-g or --global
dualInstallation
npm install <package> --link
dependencyReferences
npm install <package> --save[-dev|-optional]
--save or --save-dev or --save-optional
updateDependencies
npm install
testingNode.js
“

TDD is to coding style as yoga is
to posture. Even when you're not
actively practicing, having done so
colors your whole life healthier.

”

j. kerr
assertingCorrectness
var	
  assert	
  =	
  require('assert');
assert(value)
	
  	
  	
  	
  	
  	
  .ok(value)
	
  	
  	
  	
  	
  	
  .equal(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .deepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notDeepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .strictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notStrictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .throws(block,	
  [error])
	
  	
  	
  	
  	
  	
  .doesNotThrow(block,	
  [error])
	
  	
  	
  	
  	
  	
  .ifError(value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var assert = require('assert');
// Will pass
assert.ok(true);
// Will throw an exception
assert.ok(false);
1 var assert = require('assert');
2
3 // Will throw 'false == true' error
4 assert.ok(typeof 'hello' === 'number');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
assert.js:104
	
  	
  throw	
  new	
  assert.AssertionError({
	
  	
  	
  	
  	
  	
  	
  	
  ^
AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  at	
  Object.<anonymous>	
  (my-­‐test.js:7:8)
	
  	
  	
  	
  at	
  Module._compile	
  (module.js:449:26)
	
  	
  	
  	
  at	
  Object.Module._extensions..js	
  (module.js:467:10)
	
  	
  	
  	
  at	
  Module.load	
  (module.js:356:32)
	
  	
  	
  	
  at	
  Function.Module._load	
  (module.js:312:12)
	
  	
  	
  	
  at	
  Module.runMain	
  (module.js:487:10)
	
  	
  	
  	
  at	
  process.startup.processNextTick.process._tick...
$	
  _
Chai Assertion Library
github: chaijs/chai
install: npm install chai
isTrue,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isFalse,
isNull,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNull,
isUndefined,	
  	
  	
  	
  	
  	
  isDefined,
isFunction,	
  	
  	
  	
  	
  	
  	
  isNotFunction,
isArray,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotArray,
isBoolean,	
  	
  	
  	
  	
  	
  	
  	
  isNotBoolean,
isNumber,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNumber,
isString,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotString,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  include,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  lengthOf,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  operator,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  closeTo	
  
isObject,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotObject,
typeOf,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notTypeOf,
instanceOf,	
  	
  	
  	
  	
  	
  	
  notInstanceOf,
match,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notMatch,
property,	
  	
  	
  	
  	
  	
  	
  	
  	
  notProperty,
deepProperty,	
  	
  	
  	
  	
  notDeepProperty,
propertyVal,	
  	
  	
  	
  	
  	
  propertyNotVal,
deepPropertyVal,	
  	
  deepPropertyNotVal,

additional
assertions
var	
  assert	
  =	
  require('chai').assert;
1 var assert = require('chai').assert;
2
3 // Will throw 'expected 'hello' to be a number'
4 assert.isNumber('hello');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
expected	
  'hello'	
  to	
  be	
  a	
  number
$	
  _
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var chai
= require('chai')
, assert = chai.assert;
chai.Assertion.includeStack = true;
// Will throw and display stack
assert.isNumber('hello');
testDriven
Exceptions alone are insufficient
$	
  node	
  my-­‐test.js
assert.js:104
	
  	
  throw	
  new	
  assert.AssertionError({
	
  	
  	
  	
  	
  	
  	
  	
  ^
AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  at	
  Object.<anonymous>	
  (my-­‐test.js:7:8)
	
  	
  	
  	
  at	
  Module._compile	
  (module.js:449:26)
	
  	
  	
  	
  at	
  Object.Module._extensions..js	
  (module.js:467:10)
	
  	
  	
  	
  at	
  Module.load	
  (module.js:356:32)
	
  	
  	
  	
  at	
  Function.Module._load	
  (module.js:312:12)
	
  	
  	
  	
  at	
  Module.runMain	
  (module.js:487:10)
	
  	
  	
  	
  at	
  process.startup.processNextTick.process._tick...
$	
  _
We need a testing framework!
mocha

simple, flexible, fun
mocha

github: visionmedia/mocha
install: npm install -g mocha
$	
  npm	
  install	
  -­‐g	
  mocha
$	
  mkdir	
  test
$	
  mocha
	
  	
  
	
  	
  ✔	
  0	
  tests	
  complete	
  (1ms)
$	
  
var	
  mocha	
  =	
  require('mocha');
tddSyntax
suite('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  test('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
./test/my-test.js
1 var assert = require('chai').assert;
2
3 suite('Assertions', function() {
test('should pass on truthiness', function() {
4
assert.ok(true);
5
});
6
test('should fail on falsiness', function() {
7
assert.ok(false);
8
});
9
10 });
11
12
13
14
15
16
$	
  mocha	
  -­‐-­‐ui	
  tdd	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
groupedTests
groupSyntax
suite('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  suite('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  test('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  });
});
1 var assert = require('chai').assert;
2
3 suite('Assertions', function() {
suite('of truthiness', function() {
4
test('should pass on true', function() {
5
assert.isTrue(true);
6
});
7
test('should pass on false', function() {
8
assert.isFalse(false);
9
});
10
});
11
suite('of type', function() {
12
test('should pass on number', function() {
13
assert.isNumber(5);
14
});
15
});
16
17 });
18
$	
  mocha	
  -­‐-­‐ui	
  tdd	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  true	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  false	
  
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  

	
  	
  ✔	
  3	
  tests	
  complete	
  (6ms)
$	
  _
pendingTests
pendingSyntax
suite('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  suite('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  test('should	
  do	
  stuff	
  someday');
	
  	
  	
  	
  });
});
1 var assert = require('chai').assert;
2
3 suite('Assertions', function() {
suite('of truthiness', function() {
4
test('should pass on true', function() {
5
assert.isTrue(true);
6
});
7
test('should pass on false', function() {
8
assert.isFalse(false);
9
});
10
});
11
suite('of type', function() {
12
test('should pass on number', function() {
13
assert.isNumber(5);
14
});
15
test('should pass on object');
16
});
17
18 });
$	
  mocha	
  -­‐-­‐ui	
  tdd	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  true	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  false	
  
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  1	
  test	
  pending
$	
  _
setupTeardown
setup();
teardown();
setupTeardown
suite('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  setup(function(){
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  };
	
  	
  	
  	
  suite('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  test('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  	
  	
  	
  	
  teardown(function(){
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  	
  	
  	
  	
  };
	
  	
  	
  	
  });
});
asynchronousTests
asynchronousSyntax
test('it	
  should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
asynchronousSyntax
test('it	
  should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
test('it	
  should	
  return	
  2	
  items',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  function(err,	
  res)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  if	
  (err)	
  return	
  done(err);
	
  	
  	
  	
  	
  	
  	
  	
  res.should.have.length(2);
	
  	
  	
  	
  	
  	
  	
  	
  done();
	
  	
  	
  	
  });
});
All Mocha functions accept this callback
1 suite('When searching for Apples', function(done) {
setup(function(done){
2
items.save(['fiji apples',
3
'empire apples'], done);
4
});
5
test('it should not error', function(done) {
6
search.find("Apples", done);
7
});
8
test('it should return 2 items', function(done) {
9
search.find("Apples", function(err, res) {
10
if (err) return done(err);
11
res.should.have.length(2);
12
done();
13
});
14
});
15
16 });
17
18
simplifyExecution
be nice to yourself:
$	
  mocha	
  -­‐-­‐ui	
  tdd	
  -­‐-­‐reporter	
  spec

should be simplified to
$	
  make	
  test

and

$	
  npm	
  test
./makefile
1 # Makefile for sample module
2
3 test:
mocha --reporter spec --ui tdd
4
5
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
./makefile
1 # Makefile for sample module
2
3 test:
mocha 
4
--reporter spec 
5
--ui tdd
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
./package.json
1 {
"name": "sample",
2
"version": "0.1.0",
3
"devDependencies": {
4
"chai": "~1.2.0"
5
},
6
"scripts": {
7
"test": "make test"
8
}
9
10 }
11
12
13
14
15
16
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
$	
  npm	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
eliminate global dependency
$	
  npm	
  install	
  mocha	
  -­‐-­‐link
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui tdd
4
5
6 .PHONY: test
7
8
9
10
11
12
13
14
15
16
17
18
update dev dependencies
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  git	
  diff	
  package.json	
  
diff	
  -­‐-­‐git	
  a/package.json	
  b/package.json
index	
  439cf44..3609bb9	
  100644
-­‐-­‐-­‐	
  a/package.json
+++	
  b/package.json
@@	
  -­‐1,5	
  +1,7	
  @@
	
  {
	
  	
  	
  "name":	
  "sample",
-­‐	
  	
  "version":	
  "0.1.0"
+	
  	
  "version":	
  "0.1.0",
+	
  	
  "devDependencies":	
  {
+	
  	
  	
  	
  "mocha":	
  "~1.4.0",
+	
  	
  	
  	
  "chai":	
  "~1.2.0"
+	
  	
  }
	
  }
notificationSystems
slowThreshold

mocha --slow <ms>
-s <ms> or --slow <ms>
$	
  mocha	
  -­‐-­‐reporter	
  spec	
  -­‐-­‐slow	
  5
	
  	
  When	
  accessing	
  the	
  Ticket	
  API
	
  	
  	
  	
  with	
  valid	
  Morale	
  credentials,
	
  	
  	
  	
  	
  	
  and	
  with	
  a	
  project	
  that	
  exists,
	
  	
  	
  	
  	
  	
  	
  	
  getting	
  a	
  list	
  of	
  tickets
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ✓	
  should	
  return	
  without	
  an	
  error	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ✓	
  should	
  return	
  a	
  populated	
  array	
  (5ms)
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ✓	
  should	
  contain	
  a	
  task	
  or	
  bug	
  ticket	
  
	
  	
  	
  	
  	
  	
  	
  	
  adding	
  a	
  new	
  ticket
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ✓	
  should	
  return	
  without	
  an	
  error	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ✓	
  should	
  return	
  the	
  new	
  ticket	
  (11ms)

	
  ✔	
  5	
  tests	
  complete	
  (22ms)
$	
  _
continuousTesting
mocha --watch
-w or --watch
$	
  mocha	
  -­‐-­‐watch

	
  ✔	
  5	
  tests	
  complete	
  (22ms)
	
  ^	
  watching
Growl
mac: apple app store
win: growlForWindows.com
also: growlNotify
growlNotifications
mocha --growl
-G or --growl
⌘S
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui tdd
4
5
6 watch:
@./node_modules/.bin/mocha 
7
--reporter min 
8
--ui tdd 
9
--growl 
10
--watch
11
12
13 .PHONY: test watch
14
15
16
17
18
behaviorDriven
tddSyntax
suite('Test	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  test('Do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});

bddSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui bdd
4
5
6 watch:
@./node_modules/.bin/mocha 
7
--reporter min 
8
--ui bdd 
9
--growl 
10
--watch
11
12
13 .PHONY: test
14
15
16
17
18
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec
3
4
5
6 watch:
@./node_modules/.bin/mocha 
7
--reporter min 
8
--growl 
9
--watch
10
11
12
13 .PHONY: test
14
15
16
17
18
setupTeardown
before();
beforeEach();
after();
afterEach();
setupTeardown
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  before(function(){
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  };
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  that	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  	
  	
  	
  	
  afterEach(function(){
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  	
  	
  	
  	
  };
	
  	
  	
  	
  });
});
There is no tdd equivalent to ‘each’
tddMethods
suite();
test();
setup();
teardown();

bddMethods
describe();
it();
before();
after();
beforeEach();
afterEach();
expectAssertions
assertSyntax
assert.isObject(person);
assert.property(person,	
  "age");
assert.isNumber(person.age);
assert.equals(person.age,	
  34);

expectSyntax
expect(person).to.be.an('object');
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.a('number')
	
  	
  	
  	
  .that.equals(34);
var	
  expect	
  =	
  require('chai').expect;
assertionChains
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.to
.be
.been
.is
.that
.and
.have
.with

syntaxSugar
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.property

subjectChange
from original object
expect(person)
	
  	
  .that.is.an('object')
	
  	
  .with.property('address')
	
  	
  	
  	
  .that.is.an('object')
	
  	
  	
  	
  .with.property('city')
	
  	
  	
  	
  	
  	
  .that.is.a('string')
	
  	
  	
  	
  	
  	
  .and.equals('Detroit')
shouldAssertions
assertSyntax
assert.isObject(person);
assert.property(person,	
  "age");
assert.isNumber(person.age);
assert.equals(person.age,	
  34);

shouldSyntax
person.should.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.a('number')
	
  	
  	
  	
  .that.equals(34);
var	
  should	
  =	
  require('chai').should();
var	
  chai	
  	
  	
  =	
  require('chai')
	
  	
  ,	
  expect	
  =	
  chai.expect
	
  	
  ,	
  should	
  =	
  chai.should();
assertionChains
same as expect style*
except for existence
expect(foo).to.not.exist;
expect(bar).to.exist;
should.not.exist(foo);
should.exist(foo);
skippedTests
skipSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it.skip('should	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
describe.skip('This	
  entire	
  suite	
  will	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
1 describe('Assertions', function() {
describe('of truthiness', function() {
2
it('should pass on truthiness', function() {
3
assert.isTrue(true);
4
});
5
it('should pass on falsiness', function() {
6
assert.isFalse(false);
7
});
8
});
9
describe('of type', function() {
10
it.skip('should pass on number', function() {
11
assert.isNumber(5);
12
});
13
it('should pass on object');
14
});
15
16 });
17
18
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness	
  
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  2	
  test	
  pending
$	
  _
Skip is available in bdd only
mockingObjects
JavaScript ships with a mocking framework
...it’s called JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var me = {firstName: 'Jay'
, lastName: 'Harris'
, getFullName: function() {
return this.firstName +
' ' +
this.lastName; }};
// Returns 'Jay Harris'
me.getFullName();
me.getFullName = function() { return 'John Doe'; };
// Returns 'John Doe'
me.getFullName();
nock

HTTP Mocking Library
nock

github: flatiron/nock
install: npm install nock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var http = require('http');
var reqOptions = {
host: 'api.twitter.com',
path: '/1/statuses/user_timeline.json?' +
'screen_name=jayharris'
};
var resCallback = function(res) {
var responseData = '';
res.on('data', function(chunk) {
responseData += chunk;
});
res.on('end', function() {
console.log(responseData);
});
};
http.request(reqOptions, resCallback).end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Returns live Twitter data
http.request(reqOptions, resCallback).end();
var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
// Returns live Twitter data
http.request(reqOptions, resCallback).end();
nock

nock.recorder.rec(	
  );
nock.recorder.play(	
  );
Sinon.js

Spies, Stubs, & Mocks
Sinon.js

github: cjohansen/Sinon.JS
install: npm install sinon
browserTesting
Zombie.js Fast, headless browser
Zombie.js

github: assaf/zombie
install: npm install zombie
loadTesting
nodeload

Performance Suite
nodeload

github: benschmaus/nodeload
install: npm install nodeload
activelyPractice
Color your whole life healthier
jay harris

P R E S I D E N T

jay@aranasoft.com
#testdrivennode
@jayharris

Test driven node.js