Unit testing CoffeeScript with QUnit

I got bitten by the CoffeeScript bug and decided that I liked it enough to try to add CoffeeScript support to Cheezburger.com. Paul Betts’ very cool SassAndCoffee library has a method which compiles CoffeeScript to JavaScript which I could easily integrate into our script serving system.

I’ve also been bitten by the QUnit bug so before I enable CoffeeScript on Cheezburger.com, I want to make sure that I can unit test whatever CoffeeScript we write. A quick Google search yielded next to nothing about testing CoffeeScript but I was feeling inventive and came up with the following way to use QUnit with CoffeeScript.

Important Gotcha

Since we’re going to load .coffee scripts via jQuery.get(), they must be served by a web server. They will not load off the local file system if you simply open index.htm locally. If anyone finds a way around this, feel free to comment on the gist.

I enabled IIS Express to serve .coffee files by adding the following element to applicationhost.config in the configuration/system.webserver/staticContent element:

<mimeMap fileExtension=”.coffee” mimeType=”text/plain” />


Here is a contrived Dog class and a test for it:

And here’s the index.htm which runs the tests:

I started out with the normal set of QUnit files (index.htm, the css, and js), then included the coffee-script.js which enables us to execute CoffeeScript written in a <script type=”text/coffeescript”></script> tag. My usage of this tag in the code was completely unnecessary, but I thought this example would be more interesting if it was ALL CoffeeScript.

The scriptsToTest variable is a list of paths to .coffee files which will get loaded on the page. The tests variable is similar, but holds the tests. I split these up simply for readability.

The loadCoffee function spins through the contents of each of the files handed to it, executes the CoffeeScript compiler on them, and injects a script tag containing the compiled code into the page.

It’s important to include the “bare: on” option when calling the CoffeeScript.compile function. If bare is off (false), then the compiled code will be wrapped in a function so that declared variables get declared globally. My tests expect the Dog class to be declared globally, so I set bare to on.

Here’s a zip file full of all the files to make this example run (except for IIS Express):


This entry was posted in Development, Uncategorized. Bookmark the permalink.

5 Responses to Unit testing CoffeeScript with QUnit

  1. Eli Thompson says:

    While I was developing this approach, I ran into some strange situations where the Dog class wasn’t loaded before the test was executed on it. I couldn’t reproduce it so I’m guessing that there may be a race condition while loading the classes and the tests.

  2. I don’t see you using $(document).ready(function(){})… that will fire the function once all of the page has loaded.

    Or maybe you know something about $() that I don’t know.

    Also, I like how you’re compiling on the fly. Can lint be done on the fly like this too for pure awesome?!

  3. Eli Thompson says:

    @Justin The first line, “$ ->” says call $ as a function and pass in an anonymous function as the argument where the body of that function is all the rest of the code, so it is doing as you suggested! I did try to run the code without waiting for the DOM to load and bad things happened; you had a good instinct to look for that!

    Linting eh? I’d like to hear more about what you think. I’ll ask you at work today 😉

  4. Josh Barber says:

    Eli have you tried the Coffeescript extension for Visual Studio? It comes with the Coffeescript compiler and builds whenever you save the file:


  5. I noticed your difficulty using a local html file. If you have a local server, however, you can just use “localhost” (http://localhost/path/to/your/code) which should satisfy the browser. I used this quite a bit for WebGL stunts. I did have to put a few sim-links in the server’s Documents directory.

Leave a Reply

Your email address will not be published. Required fields are marked *