After messing with potentially running the tests with the Jasmine Maven plugin, inside NodeJS, and headless webkit, I came back to the simplest solution. I came back because after much heartache, I just wanted something to work. Jasmine standalone has done the trick.
Test Runner Setup
RequireJS paths can be tricky. For some reason, the trickiness seems to increase inside the testing environment. To try and make relative pathing easier, I’ve included my test directory inside my app’s js directory, like so:
1 2 3 4
Jasmine standalone just uses a plain old HTML file for its runner. My RequireJs Jasmine runner structure looks like this:
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 34 35 36 37 38 39
Import everything that is global via the old-fashioned method – just a
<script/> tag in the
<head/>. Then, write and import your specs as RequireJS modules, and just require them in your runner.
A Runner Per main.js
When I’m writing RequireJS modules in the app, I’m using relative paths. These paths are always relative to the main module that uses these other require modules. Thus, when you configure your runner, the
baseUrl needs to point to the directory of the main module that in turn imports the modules under test. And thus it follows that you’ll actually need a separate runner for each main module in your app. So, if you’re a true single-page app, you’ll only have one module. But, for example, in the app I’m currently dev’ing, we have a public main.js and an admin main.js, so we have a public-runner.html and an admin-runner.html.
This is only an issue if your app uses relative paths. If you use absolute paths in your app modules, the new issue will be that you’ll have to be able to run your tests from the exact context from which your app usually runs.
Require and Jquery
Just a note: Even though I use
require-jquery.js in my app, I found that for some reason Jasmine didn’t appreciate that, and I had to import
require.js separately. If anyone knows why, I’d love to be enlightened.
Run on an HTTP Server
This probably goes without saying for anyone that has used require for some time, but since require dependencies are asynchronously loaded, you’re going to run into problems with cross domain policies in your local dev. I use Chrome, and I immediately start seeing errors if I run from the filesystem:
You could start Chrome with a flag to ignore this cross-domain policy, but I prefer to just spin up a little http server action with nginx and edit
/etc/nginx/sites-available/default to point the server root at your projects
js/ directory and restart nginx (
sudo service nginx restart). Then get to your runner at something like
Require Test Fixtures
Another reason to run your tests on an http server is for ease of importing text fixtures. The way we’ve set up our runner, the baseUrl is configured to be the js root directory, which allows our app code to work unchanged, but now we’ve made it potentially harder for us to get to test dependencies that aren’t in the application code area. This may just be my own ignorance of RequireJS shining through, but when I set
baseUrl: '../admin/' for my
admin-runner.html and try to import a test fixture w/ relative paths in the test, the paths are supremely messed up. Thus, with this directory structure:
1 2 3 4 5 6 7 8
I’m forced to import with server absolute paths like this:
1 2 3 4 5 6 7
So, again, if I wasn’t running tests on an Http server, this wouldn’t work.
Secrets of the Fire Swamp