Tuesday, June 12, 2012

Using Webstorm or PHPStorm and Mocha for unit testing in Node.js




I have been working on a node.js project and decided I wanted to get some unit testing going .  I did some research and there are a lot of test frameworks out there for node.  You can use Jasmine, node-unit, Expresso, Mocha or a myriad of other frameworks.  Apparently this is a problem people have decided to solve over and over and over.  After a bit of research I settled on Mocha.  It’s written by the same guy who writes the awesome Express library and is well supported. 

You can write your unit tests in a variety of formats whether you like BDD or TDD and you can write them in either javascript or coffeescript.  Mocha is pretty deep and supports all sorts of input and output formats. There is actually a great tutorial on peepcode called Full Stack Node JS that goes into a lot of stuff on getting started with node and has a lengthy section on testing with Mocha. Spend the $12 right now it’s worth it. 

After you get done watching that you should be able to write some basic unit tests in javascript or coffeescript and run them from the command line using npm test.  I say “should” because like all things “node”, documentation is pretty sparse.  Be prepared to do some googling. 

So now that I was able to write unit tests and run them from the command line I should've been happy as a clam right?  Wrong.  Typically when I’m writing code I like to write a test method and then run it in a debugger.  I did some searching around and couldn't fine a way to do this with Webstorm, my choice of javascript editor.  I like Webstorm because you can debug your javascript from within the IDE and single step through the code. If you need to do PHP stuff you probably want to buy PHPStorm as it has all of the functionality of Webstorm plus the ability to work with PHP.  I bought Webstorm first but 6 months after the fact the people at JetBrains were nice enough to give me a discount when I upgraded to PHPStorm.

When you run the Mocha test framework it runs a node.js program that takes a list of test files on the command line.  I realized that if I could figure out a way to pass the files without having to use the command line I could probably debug my js files that are loaded by Mocha.  My plan was to run the mocha.js file from Webstorm in debug mode and that would then load up my test js files. After spending a few hours digging into the Mocha code, it looked like the plumbing was there for what I needed but it was still going to take some time to figure out exactly what to do.

I don’t know why but for some reason I decided to poke around a bit on TJ Holowaychuk’s blog (the author of Mocha).  I clicked on “About” which took me to the footer of his blog. By coincidence the last blog entry on the page from March 24th said:

“A new JS API was added, which mocha(1) now utilizes. This higher-level JS API will make it easier for those who want to script the testing process with Mocha. I have yet to document this API but it looks like this:”

There it was right in front of me.  20 lines of code that would help me do exactly what I needed to put together my own “runner” file for doing my unit tests in a project.  Holy stroke of luck! I found the “I have yet to document this API” statement to be quite humorous since you rarely find heavily documented node.js libraries.  Here’s what I’m doing to make my test files Mocha compatible as well as debuggable from within Webstorm.

First add Mocha to your node project by doing the usual "npm install mocha" and make a directory called test.  This is where all your tests will live.  You can make subdirectories for your tests if you’ve got lots of them but make sure everything lives in test.  In test you create a base file called testRunner.js.  This file has the code you need to load your other tests and it is the file you will run in debug mode from within Webstorm.  

Your project should look something like this:




The code for testRunner is as follows

var testFiles=["test/_helper.js","test/tests.js","test/tests.coffee"];


var Mocha = require('mocha');


var mocha = new Mocha;


mocha.reporter('spec').ui('bdd');


for (var i =0;i<testFiles.length;i++){


 mocha.addFile(testFiles[i]);


}

var runner = mocha.run(function(){

                console.log('finished');

});

The array at the top is where you put the names of the files that contain all your tests.  As you can see above I’m going to run 3 test files named _helper.js,tests.js, and tests.coffee.  The _helper.js is stub file and all it contains is the follow line of code:

require('coffee-script');

If you’re not going to write any of your test scripts in coffeescript then you don’t need to include this file.  If you are, then make sure it’s the first file in your list of tests.

The next lines of code load Mocha, create an instance of it, specify that you want to use the behavior driven development style of tests, add the test files, and then run them. When you run this from Webstorm the output from your tests wlll show up in the Webstorm console window and you can single step through the code for debugging. 

I hope this helps some of the other people out there who were trying to figure out how to work with Mocha and Webstorm.

3 comments:

  1. Great article :). Thanks a lot for posing, worked great.

    ReplyDelete
  2. Have you tried creating a run/debug configuration and pointing the path to node appjs file to "../yourpath../usr/lib/node_modules/mocha/bin/_mocha" , might be easier

    ReplyDelete