EDIT: Note that I no longer advocate the use of RequireJS. If you still find this useful, that’s awesome.
Problems with Jasmine
However, testing became a problem. I needed a way for Jasmine to play well with RequireJS. I could just require the modules I want inside a test, then
waitFor it to be loaded, but that felt rather messy. So, I decided to patch Jasmine’s
describe methods to do what I wanted.
Adding RequireJS Support to Jasmine
When the Jasmine server runs, it exposes a path to your app’s /public folder under /public. The problem is that you would normally reference those files from your website root. So, your bootstrap file needs to know if it is being used in a testing environment. You can test for that and act accordingly.
The jasmine.yml file doesn’t need to include any specific (or wildcarded) spec files.
Patching it and describe
This step involved a lot of work. Essentially, we override the global
describe methods to support the following.
- One argument => pending
- Two arguments => normal behavior
- Three arguments => RequireJS behavior
The standard method for using RequireJS to import a module is to call
define ['module1', 'module2'], (module1, module2) ->. So, I decided to follow the same signature in the it and describe calls, making this valid.
When using the Jasmine gem, the Jasmine test runner page is setup to run the tests in a
window.onload event handler. The problem here is that we want to wait for our modules to be loaded before registering our specs. The new spec methods will use RequireJS to load the necessary modules asyncronously. If we leave the
window.onload handler there, it will run before our modules are loaded and our specs will never be registered.
Thus, we need to wait for our specs to be registered before running the test suite. I handled this with a simple load counter, but there’s probably a race condition with nested module requirements in specs. For now, this works pretty well.
The traditional use of the jasmine.yml configuration file has you list all of your CSS files. It seems that people usually do this so that they can test the visibility
display: none or display: block of an element. I feel that this is far from necessary. So, I created a little tool (called Hidey, requires cssom) to extract out your
display: none declarations from your css files into a new smaller file. Now, you only need to include that one file to be able to test your visibilities.
Since writing that tool, however, I’ve changed my view on testing visibility. I’d rather let my CSS handle that and simply test for the existence of a class that should imply visibility. The simplest example would be to test an element for a
hide class if you want it to be hidden.
Putting It All Together
Now, I can write specs that look like this!
I considered submitting a pull request to Jasmine to add RequireJS support, but I’m not completely happy with how it works right now. The more I manipulate Jasmine to do what I want, the more I realize I should write my own testing framework (again, although attempt #1 was many years ago and pretty awful). But, I’ll save that for another day.