Sunday, 8 June 2008

Test Driven JavaScript Code Coverage using JSCoverage

Continuing on our adventures in TDD JavaScript land and we reach for the code coverage tool. The mighty Google returns JSCoverage as the first hit for JavaScript code coverage, which means it must 'be' good, right? Let's find out how well it plays with QUnit.

You can download JSCoverage as a precompiled Linux or Windows build.
So I downloaded the pre-built Windows build.
And upon opening the zip we get a jscoverage.exe and a whole bunch of documentation.
In the grand tradition associated with the previous TDD JavaScript blog post, I won't read the documentation I just downloaded. Instead I'll have a quick scan of the online manual.
JSCoverage takes two arguments, a source directory and a destination directory. Anything in the source directory gets instrumented. Since I don't want to instrument the QUnit and JQuery libraries I ...
  • move those into a folder structure of their own,
  • and put my code in its own folder structure,
  • then I run jscoverage eprimecode c_eprimecode



Err...OK, now I have a new folder called c_eprimecode... I better read the instructions...
Oh, OK, so in c_eprimecode I now have a file called jscoverage.html, and I can put the path of test_eprime.htm and when I click GO it will load that page, thereby running all the tests against the instrumented version of eprime.js
easy...



And... it worked!



100% coverage. You can see I've added a few more tests and a few more lines of code since you last saw eprime.js and I felt pleased that my TDD efforts had led to 100% coverage.
I can click on the eprime.js link and see the code coverage metrics.



All covered lines have a green count next to the line number, and the number in the green box shows how many times that line ran during the testing. If we did not cover a line then we see a read box with the ominous 0 in it. So scanning through the source for the big bad red becomes very easy.
And that only took about 5 minutes. What can I do now? Ah, Inverted mode.
If I add a line into my test_eprime.htm like the following
<button onclick='window.open("path/to/jscoverage.html");'>Coverage report</button>

Then I can run my test_eprime.htm like normal, but click to the coverage report.

So I do that...







But now I get mixed up. I start clicking on the coverage button when in the non-instrumented version and get a 404, so I want to fix that.

I know... I'll add some JavaScript so that the button only displays on the instrumented code page...

<button id="coveragebutton"
        onclick='window.open("jscoverage.html")'>Coverage report</button>
<script>   
if (typeof(_$jscoverage)=='undefined')      
document.getElementById("coveragebutton").style.display="none";
</script> 

And now, just to finish off, a little cmd script to automate it all for me...


instrument_eprimecode.bat
jscoverage eprimecode c_eprimecode
c_eprimecode\test_eprime.htm



So now I have QUnit Unit tests and JScoverage all running together.



Summary


I do not know how well JScoverage copes with more complicated JavaScript. As my coding skills in JavaScript improve I guess I'll find out. But certainly for the moment it does the job for me.

I use code coverage as an 'after check'. So I do my TDD and get it all as good as I can, then I just double check, but examining the code coverage:

  • did I miss anything?
  • do I care about the code that got missed?
JScoverage does that for me just now.

Other coverage tools for JavaScript exist: ProtoCov, the commercial JavaScript coverage Validator, and some sort of FireBug add on. But these are noted for future investigation as I have not used these. If you have used these please comment on them below.


SideNote: not really related to the above, but I didn't want to lose it. I saw this JSMock (mocking library) that I need to try out at some point.

4 comments:

  1. Hello! Thanks for the article.

    I'd just like to point out that the jscoverage program accepts a --no-instrument option so that you don't have to rearrange the folder structure of your code to avoid instrumenting certain files. For example, to avoid instrumenting JQuery you could add something like --no-instrument=jquery-latest.js on the command line.

    Hi Ed, thanks for the info and the comment, but more importantly - thanks for JSCoverage.

    ReplyDelete
  2. [...] Test Driven JavaScript Code Coverage using JSCoverage [...]

    ReplyDelete
  3. [...] deal with sophisticated concepts such as currying, callbacks, closures, array comprehensions, and test driven development in [...]

    ReplyDelete
  4. [...] have found a post that describes how to use JSCoverage with QUnit that I successfully used to integrate JSCoverage with my unit [...]

    ReplyDelete