Testdriving Javascript With jqUnit
Whew… looks like my “Week of javascript TDD frameworks will really turn into a month of ‘em. Fine by me though, I like options. For a bit of randomness, I’m going to try out jqUnit. jqUnit is a TDD framework that takes quite a different approach… it is structured much like jquery is and tests are laid out in a jquery kind of way. Although it depends on jquery to run, your SUT does not have to have jquery as a dependency. Anyhow, let’s take a quick dive into the dirty details and then get started.
The Dirty Details
Basically another xUnit framework, but the syntax is radically different from any framework I’ve seen, xUnit or BDD. instead of your usual “assertXXXX” or spec syntaxes, it simply uses yep and okay . Most importantly, this is the framework used by jQuery to test itself.
License
The MIT License of course!
Last Updated
March 14, 2008
Support
No mailing lists or usergroups found, but it’s assumed you can contact the authors listed on the project page if you need help.
Fair Enough, Let’s See Some Code!
Setup is easy enough… go grab jqUnit off of google code and extract the zip file to any given directory. I found the included examples a little difficult to follow, but pretty much it goes like this:
- expect(n)
- This basically says you expect n assertions to happen in this test. Pretty useful for tests where you might make assertions in a provided callback.
- equals(expected, actual)
- Pretty obvious, shorthand for assertEquals
- ok(value)
- Same as assertTrue
That’s pretty much all I needed for my HTML5 placeholder example. However there is a lot more if you’re willing to check under the hood… start() and stop() provide some nice control for testing things that occur over time (ajax callbacks, intervals and timeouts). With all of this in mind, I wrote a simple test for the html5 placeholder:
<script>
with (jqUnit) {
module('Html5Emulator');
var dom = $('<div></div>');
dom.append("<input type='text' value='' placeholder='Hello' id='foo'>");
var input = $('#foo', dom);
var emu = new Html5Emulator();
test('Populates placeholder text in value attribute', function(){
emu.emulatePlaceholders(dom);
equals(input.val(), "Hello");
});
test('Blanks value on focus', function(){
emu.emulatePlaceholders(dom);
input.focus();
equals(input.val(), "");
});
test('Replaces value on blur if value is empty', function(){
emu.emulatePlaceholders(dom);
input.focus();
input.blur();
equals(input.val(), "Hello");
});
test('Does not replace value on blur if value is different', function(){
emu.emulatePlaceholders(dom);
input.focus();
input.val("Foobarbaz")
input.blur();
equals(input.val(), "Foobarbaz");
});
test('If value is set does not blank on focus', function(){
emu.emulatePlaceholders(dom);
input.val("Foobarbaz")
input.focus();
equals(input.val(), "Foobarbaz");
});
}(jQuery);
</script>
</head>
I’m sure this is just scratching the surface and there’s probably a lot more underneath, but as always the code for this example is available on github for your viewing pleasure… you can look at jquery’s own test suite if you wish to explore it’s features further.
What I Liked
I think the main thing I look for in a testing framework is a very simple runner… jsunit sunk a lot of my time chasing after the cause of tests not getting loaded into the test runner and inspec required me to install an entire implementation of ServerJS to run the tests. The thing I’ve liked about other frameworks is the ability to just open the test file up and see it run. jqUnit has this capability and I like it for that.
- Nicely self contained tests… no global scope polution
- jquery based syntax
- I like
expect… I’ve been in the boat before where I wanted to put an assertion in a callback but instead had to write some scoping magic to assign a var to true in a callback and then assert that. It’s a welcomed feature.
What I Didn’t Like
- The syntax was a bit confusing at first… the example tests had
expect(2)in the beginning of test methods and I had no idea what it was - Where’s the setup? Tear down? I couldn’t find any methods that resembled before/after features in any way
- There was little documentation… I admit I cracked open the source at first try to see what was going on. However some further searching revealed some blog posts to learn from.
Closing Thoughts
Sadly I found jqUnit to be HIGHLY unreadable at first… if you look at the example test that ships with the download, almost every single line has a comment, and for good reason! At first glance, expect(1); and yep(f.doSomething()); doesn’t really tell me much.
Other than that though, it wasn’t too shabby… and you have to give it props as it’s what jQuery’s automated tests are written in. It’s compatibility with jsUnit is also very nice for those with jsUnit expeirence.
What’s Next?
There’s still a few more frameworks on my list to check next, from Crosscheck, YUI Test and even “the other jsUnit.” I’m also considering covering a few of the mocking/stubbing frameworks out there, going back over jspec to showcase it’s own built in stub/spy syntax, Jack, JsMock, and much much more!
(Hopefully I’ll be able to find time to do this between other things, such as my dogs tearing up the entire hallway carpet while I was at work). Cheers! ![]()
If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!














August 7th, 2009 at 2:20 pm
Just a correction regarding setup/teardown: they are there. As Colin Clark himself wrote, “I’ve added support for setUp() and tearDown() functions which get run before and after each test. I’ve created a simple object called TestCase. Its constructor takes three arguments: the module’s name, your setUp function, and your tearDown function.”
http://groups.google.com/group/jquery-en/msg/b6b7ff05f5f06945?pli=1