with javascript
Tester, c'est douter ?
HELL NO !
Quality is never an accident; it is always the result of intelligent effort.
John Ruskin
Software testing proves the existing of bugs not their absence.
Runners
Frameworks
Tools
Ecrire les tests d’abord => TEST FAIL
Ecrire le code jusqu'à ce que ça passe => TEST OK
⇒ Permet de ne pas se focaliser sur le besoin,
⇒ Meilleur moyen de ne pas oublier.
Syntaxe : suite(), test(), ...
TDD avec une syntaxe plus lisible.
You should not test implementation, but instead behavior.
BDD tests should be more focused on the features, not the actual results
Syntaxe : describe(), it(), ...
suite('Counter', function() {
test('tick increases count to 1', function() {
var counter = new Counter();
counter.tick();
assert.equal(counter.count, 1);
});
});
describe('Counter', function() {
it('should increase count by 1 after calling tick', function() {
var counter = new Counter();
var expectedCount = counter.count + 1;
counter.tick();
assert.equal(counter.count, expectedCount);
});
});
npm install -g mocha
Test framework
describe('hooks', function() {
before(function() {
// runs before all tests in this block
});
after(function() {
// runs after all tests in this block
});
beforeEach(function() {
// runs before each test in this block
});
afterEach(function() {
// runs after each test in this block
});
// test cases
it('should do something', function() {
// ...
});
});
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) throw err;
done(); // Call the done callback
});
});
});
});
mocha // Launch the tests
mocha --watch // Live watch
mocha --debug // Use the Node's debugger
With the global mocha command
var mocha = require('mocha');
gulp.task('test', function () {
return gulp.src('test/**/*.spec.js', { read: false })
.pipe(mocha({ reporter: 'nyan' }));
});
With a Gulp task
gulp test
gulpfile.js
mocha --reporter="spec"
nyan
Landing Strip
https://gitlab.fullsix.com/dfo-internal/mocha-training
Step 1: Branche "master"
Instructions dans le Readme
npm install chai
Assertion library
Chai is a BDD / TDD assertion library for node
chai.should();
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.length(3);
tea.should.have.property('flavors').with.length(3);
var expect = chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.length(3);
expect(tea).to.have.property('flavors').with.length(3);
var assert = chai.assert;
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);
should
expect
assert
// .include
expect([1,2,3]).to.include(2);
// .contain
expect('foobar').to.contain('foo');
// .ok (truthy)
expect('everthing').to.be.ok;
// .true
expect(true).to.be.true;
// .false
expect(false).to.be.false;
// .any
expect(foo).to.have.any.keys('bar', 'baz');
// .all
expect(foo).to.have.all.keys('bar', 'baz');
// .exist (!null && !undefined)
expect(foo).to.exist;
// .empty
expect([]).to.be.empty; expect('').to.be.empty; expect({}).to.be.empty;
// .equal
expect('hello').to.equal('hello');
// throw an error
var fn = function () { throw err; };
expect(fn).to.throw(ReferenceError);
https://gitlab.fullsix.com/dfo-internal/mocha-training
Step 2: Checkout branche "step2"
Instructions dans le Readme
npm install sinon
Test spies, stubs and mocks
Standalone test spies, stubs and mocks for JavaScript.
// Test
it('should call callAPI', function() {
const url = 'http//xxx.xx/videos/count';
sinon.spy(Media, 'callAPI');
Media.countVideos();
expect(Media.callAPI.calledOnce).to.be.true;
expect(Media.callAPI.withArgs(url).calledOnce).to.be.true;
Media.callAPI.restore();
});
// Source
class Media {
static callAPI(url) {
// ...
}
static countVideos() {
return Media.callAPI('http//xxx.xx/videos/count');
}
}
How to spy objects and methods !
// Test
it('should count the videos', function(){
var stub = sinon.stub(Media, 'callAPI');
stub.returns(100);
expect(Media.countVideos()).to.equal(100);
Media.callAPI.restore()
});
Change the behavior of a function
// Source
class Media {
static callAPI(url) {
// ...
}
static countVideos() {
return Media.callAPI('http//xxx.xx/videos/count');
}
}
it('should increment stored value by one', function() {
var storeMock = sinon.mock(store);
storeMock.expects('get').withArgs('data').returns(0);
storeMock.expects('set').once().withArgs('data', 1);
incrementStoredData();
storeMock.restore();
storeMock.verify();
});
Sinon’s mocks can be used to replace whole objects and alter their behavior similar to stubbing functions.
https://github.com/juherpin/mocha-exercises
Step 3: Checkout branche "step3"
Instructions dans le Readme
https://gitlab.fullsix.com/dfo-internal/mocha-training
Solution: Checkout branche "end"
https://gitlab.fullsix.com/dfo-internal/mocha-training
Solution: Checkout branche "ci"