Yesterday I had a bit of a bad time trying to code some tests for a web application (written in
js). The main problem was that using
requirejs needed some further configuration within tests. It didn’t take too long to find what I was doing wrong but it may be confusing at the beginning. During this post I’ll be talking about:
In order to run tasks you need to install
npm install -g grunt-cli.
nodejs works, I decided to code a card game called Dominion. There are already multiple web versions of this game, there is even an official one. Yet this is a good way of practicing modularity, testing and server/client behaviour with
Let’s show how the work tree is organized:
Let’s look at the
package.json file as it includes all the dependencies needed:
Gruntfile.js file has been simplified to match the testing part:
We are using
requirejs to load modules. Therefore we can share some the configuration with a file:
In this project I load this file only once, in the
main.js. However when having more complex configuration you should load it every time you need it.
We first start by using
selfish to create some classes that will be used in the application:
We can ignore
main.js as they are used for the
requirejs entry point and have nothing to deal with testing.
Here comes the important part which is accessing modules from the test and being able to use them. First let’s take a look at the test file:
First we require the different modules needed by
We are going to use
requirejs to load modules. This is actually different from the
require(). Then we add the configuration. The
baseUrl specifies from which point modules must be found. This path is relative to the runtime, thus when running
grunt at project root (cf
tree) we must specify files as
When loading modules within tests there’s one important thing: creating a test before calling
requirejs(). This is because
Mocha need to know tests exists. After that we can load any modules needed by the tests:
We declare a variable
Card to store the
Card class and use it later in the tests. By using the
before(done) function we ensure that classes will be available before any test. Calling
done() callback is necessary because we’re dealing with asynchronous module loading, thus we have to notify
Mocha that modules are available. If we don’t call
done(), tests will fail because they will be called before
requirejs() call ends.
it() methods are
BDD assertions style (as
TDD equivalents are
Once the setup is done we can do the tests as usual:
Remember to use the
done() callback when dealing with asynchronous code!
You can find the boilerplate here:
Gruntfile contains more targets that help development, such as:
serve: simple HTTP server
deploy: Compress and unify every
jshinton project files.
default: will run
There’s also a
Victory class to show that everything works just fine with more that one module loading.