buster + require + backbone running in browser and CI

243 views
Skip to first unread message

GotBusted

unread,
Apr 30, 2012, 5:03:01 AM4/30/12
to bust...@googlegroups.com
Hi,

I've created the attached sample app to test Buster for our project which uses RequireJS and Backbone. I got the tests running in browser and would like your feedback on how I did it and about the best way to integrate them in our CI server. Please see the README.txt file for a better explanation of what I did and our requirements.

Any feedback on best practices and similar experiences is welcome. Thank you!
sample.zip

Christian Johansen

unread,
May 2, 2012, 2:18:58 AM5/2/12
to bust...@googlegroups.com
Hi,

There's a few things you might want to change for this to run properly, especially through the server for your CI environment. The require call in the test is not recommended as it's going to be entirely random whether or not Buster will pick up your tests. The correct way to define an asynchronous test case is the following:

buster.testCase("View tests", function (run) {
    require(['module/view'], function(View) {
        "use strict";

        run(function () {
            return {
                "subview rendered?": function () {
                }
            };
        });
    });
});

Now, I realise that this is not the most sexy layout, you've got a lot of indents here. That's why the buster-amd[1] extension was developed. Unfortunately, I think buster-amd is temporarily out of commission due to a change in the latest buster release. It also does not yet work with the static html page. So for now, I'd recommend the above, possibly wrapped in a simple abstraction:

function asyncTestCase(name, dependencies, callback) {
    buster.testCase(name, function (run) {
        require(dependencies, function () {
            var deps = arguments;
            run(function () { callback.apply(this, deps); });
        });
    });
}

So your tests will look like:

asyncTestCase("View tests", ["modules/view"], function (View) {
    return {
        "something something": function () {}
});

You don't need the spec directory when you already have the test directory. Just put buster.js configuration in test/buster.js.

The static file can be generated for you from buster.js by using `buster static`, but then you'd have to install buster.

Regarding your CI environment, at the moment you cannot auto-run browsers, although it is an issue we intend to fix. The best you can do is:

buster server
Open browser at http://localhost:1111/capture, which will auto-capture it.
buster test

Hope this helps.

Christian
--
MVH
Christian

GotBusted

unread,
May 2, 2012, 6:48:48 AM5/2/12
to bust...@googlegroups.com
Hi,

Thank you for the tips!

Using the code you suggested for the async test just prints 'undefined' in the test result page.

Also, by your explanation was not clear why you say that this can randomly fail, can you elaborate please?

"sample test": function (done) {
"use strict";
require(['module/view'], function(View) {
// my assertions
done();
});
}

Thank you!

GotBusted

unread,
May 2, 2012, 7:06:55 AM5/2/12
to bust...@googlegroups.com
For anyone following this post and also struggling with buster + require here is the approach I'm following so far:

buster.testCase("View tests", {
"subview rendered?": function (done) {
"use strict";
require(['module/view'], function(View) {
done(function() {
// NOTE: Make sure the test doesn't take more than 250ms (the default, but can be configured), or it will timeout.
// Render the view in a fake element
var fakeEl = $('<div></div>');
var view = new View({'el': fakeEl});
view.render();
// Assert subview content
var expected = 'subview';
var got = fakeEl.find('div').text();
buster.assert.equals(expected, got);
})(); // Notice the call to the function returned by done!
});
}
});

I think this is the right way to do it currently but I might be wrong.

Thanks to all the guys here and on IRC that helped me get to this solution. Keep up the good work!

Christian Johansen

unread,
May 3, 2012, 2:39:34 AM5/3/12
to bust...@googlegroups.com
Hi,

While that's not incorrect, it's not the optimal way. I tried to run and fix your project, but I'm getting "Unable to load script ./module/view.js" which seems like a Require.JS problem? Is it configured correctly for your project?

In any event, a better use of the done function is:


buster.testCase("View tests", {
    "subview rendered?": function (done) {
        "use strict";
        require(['module/view'], done(function(View) {

            // NOTE: Make sure the test doesn't take more than 250ms (the default, but can be configured), or it will timeout.
            // Render the view in a fake element
            var fakeEl = $('<div></div>');
            var view = new View({'el': fakeEl});
            view.render();
            // Assert subview content
            var expected = 'subview';
            var got = fakeEl.find('div').text();
            buster.assert.equals(expected, got);
        }));
    }
});

i.e., just wrap the inner-most callback in done. If you prefer, you can call it manually too:


buster.testCase("View tests", {
    "subview rendered?": function (done) {
        "use strict";
        require(['module/view'], function(View) {
            // NOTE: Make sure the test doesn't take more than 250ms (the default, but can be configured), or it will timeout.
            // Render the view in a fake element
            var fakeEl = $('<div></div>');
            var view = new View({'el': fakeEl});
            view.render();
            // Assert subview content
            var expected = 'subview';
            var got = fakeEl.find('div').text();
            buster.assert.equals(expected, got);
            done();
        });
    }
});

However, the last one is not really recommended, as it gives Buster less control. I'd like to help you get up and running with my original suggestion though, so if you could let me know how to fix the RequireJS thing, that'd be great.

Christian
--
MVH
Christian

GotBusted

unread,
May 6, 2012, 4:12:12 AM5/6/12
to bust...@googlegroups.com
Hi,

Yes, I've opened both src/index.html and test/index.html both on Windows an Linux and they show no problems. I'm opening the files directly, not via an http server, but it also works that way. I wonder if you're facing a permissions issue...

When you say it's not the optimal way, what exactly could be improved to make it optimal?

Thank you
Reply all
Reply to author
Forward
0 new messages