Jasmine is described on its site as a ‘behaviour driven development framework for testing your JavaScript code.’ I thought I would give it a try, using it while developing a new game with my Canvasteroids framework.
First off, though, I should address the different terminology here: what is ‘behaviour driven development’ anyways? Why isn’t it called a Unit Testing framework? To understand why, you should read this article The idea that the names matter really rings true for me and it always seemed weird to me to try and test something which does not yet exist. Thinking of ‘specifications’ rather than ‘tests’ makes a lot more sense to me. Also, thinking about testing ‘units’ of code is more likely to make your tests closely coupled to your implementation, leading to maintenance headaches and unnecessary, verbose tests.
Installing Jasmine is ridiculously easy: I just downloaded the standalone project, and extracted it as the ‘specs’ folder in the Canvasteroids project. Inside it is a SpecRunner.html file.. opening up this in a browser will run the dummy tests which are there by way of example. Then I removed them so that I could run my own specs. I also installed some Jasmine Snippets for Vim to make writing specs even easier.
I created a new spec file called BreakoutSpec.js in the specs/ folder and added the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
The describe() function defines a Suite of Specs. The function given to it as its second argument contains the specs themselves. Each spec is defined by an it() function call, which similarly takes a function as its second argument. The first argument to both describe() and it() is a descriptive string which will be shown in reports. Within the it() function there are calls to expect() which will check specific things to determine whether the Spec has been fulfilled. See the list of them here. In this case we are simply checking that the Breakout game instance was created successfully. Obviously, beforeEach() is run before each spec. We need to include the spec in the SpecRunner.html file, which now looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Refreshing the SpecRunner.html file, we see that this Spec fails. There are two failures, one which is the result of a run-time error while executing the spec (because the namespace ‘breakout’ in ‘breakout.Breakout’ is undefined, and because the expectation was not met (because ‘game’ was not defined).
So, I made a new folder called ‘breakout’ in the games folder, and copied the index.html file from Asteroids into it, renaming the reference to the Asteroids game class to be Breakout. I also created the new game class in a file alongside the index.html file, called Breakout.js, with the following Ext 4 class definition in it:
1 2 3 4 |
|
So we have a Breakout class now, but how do we load it in our test runner? Why not use the Ext JS 4 Class loader, just as we do in the game itself? This is what the updated SpecRunner looks like (we also need to load the ext-foundation.js file).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Note that we made the call to Ext.Loader.setConfig(), defining the required namespace ‘breakout’ to be the relative path of the directory containing the class file. And we wrapped the Jasmine code in a call to Ext.onReady(), which will only execute when the classes required have been loaded. This is handy, because we will not have to worry about adding them to the SpecRunner, which can be a chore with other Javascript Testing frameworks I’ve used. We will however need to update the paths of the namespaces used by any classes in the application, so that any namespaces are correctly resolved. And when we run the SpecRunner again … we get the green light! The spec succeeded.
So I admit this is a trivial spec… but it should be enough to get you started with Jasmine and Ext JS4.