Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

JavaScript Testing

Completing the BDD Circle in Web Development

Trevor Lalish-Menagh, a guy who wants you to test your code @trevmex

CISQ: Consortium for IT Software Quality says...

but really...

You are an engineer.
Engineers produce quality work.
Quality work is work that you care about.
Work that you are proud to show off.
Work that you are not afriad to change.
You write JavaScript.

Writing quality JavaScript is hard...

You have to know what to do...

Namespace your functions...

var AwesomeNS = {};
AwesomeNS.rockstar = function () { // Good job, rockstar! }

Decalre your vars up top...

AwesomeNS.rockstar = function () {
    var thisIsHow = "we do it";
// No block scope, here! }

Encapsulate your code in IIFEs

(function () {
    var giveAHoot = !pollute;
// ...the global namespace! }());

And what not to do...

Don't use with...

bad = "hehe";
with (theNS) {
    // is this theNS.bad or bad.
    // Who knows!
    bad = "oh noes";

Always remember your vars...

function derp() {
    for (i = 0; i < 10; i++) {
        // You just modified
        // the global 'i'!

Stop abusing eval...

var property = 'bar';
var value = eval('foo.' + property);
value = foo[property]; // Good!

But you know all that.

Because you are a rockstar!

Come on...

None of us are perfect.

We all write bad code.

Especially JavaScript.

So we write tests.

Tests in JavaScript.

And we run them in our CI server.

Now front-end engineers can

break the build.

And that is a very good thing.

How to do it:

Live Coding Time!!!

(I am such a fool...)


NS.greeter = function (name) {
    return 'Hello ' + name + '!';
describe('greeter', function () { it('greets me', function () { expect(NS.greeter('Trevor')).toEqual('Hello Trevor!'); }); });

Jasmine with Callbacks

NS.runIfTrevor = function (name, callback) {
    if (name === 'Trevor') {
    } else {
        console.log("You aren't Trevor!");
describe('runIfTrevor', function () { it('calls callback if Trevor', function () { var callback = jasmine.createSpy(); NS.runIfTrevor('Trevor', callback); expect(callback).toHaveBeenCalledWith('Trevor'); }); });

Jasmine with Ajax

NS.greetUser = function (id) {
    return $.ajax({
        data: id,
        url: 'name.html',
        success: function (data) {
describe('greetUser', function () { it('calls greeter on success', function () { NS.greetUser(1); spyOn(NS, 'greeter'); mostRecentAjaxRequest().response({ status: 200, responseText: '{"name":"Trevor"}' }); expect(NS.greeter).toHaveBeenCalledWith('Trevor'); }); });