Most JavaScript testing frameworks run in the browser and are tightly coupled to the DOM.

I don’t care about the DOM and I definitely don’t care about the browser, at least not when I am (unit) testing my JavaScript components.

This probably needs some context; I’m not writing web sites with 5 lines of JavaScript in them you see.  I’m writing desktop like applications that run in the browser. This means I have a lot of widgets and screens that need to talk to each other. I am also doing XMLHTTP calls to the server. All the interaction needs to be tested.

I don’t want to run the tests thru the GUI. It’s to brittle. Changing an a-tag to an input-tag or moving a component on the page can easily break a test. Testing is supposed to improve productivity, not slow it down.

I use the Model-View-Presenter design pattern to design my application layer. This means I have a thin layer, call “the view”,  over my HTML that abstracts away both the DOM and with it, the browser.

The View

Let’s say I have the following component in my application. (It would probably say “search” and not “Google search”, but you get it)

image

The corresponding HTML would look something like this (ignoring the lucky-button)

<input id="q" type="text" />
<input id="search" type="button" />

I would now create a SearchView module to put an abstraction on top of this HTML (using some JQuery magic)

function SearchView(callback){
	$("#search").click(function(){
		callback($("#q").val());
	});
}

Now the rest of my code will depend on the SearchView function, and only the SearchView function will depend on the browser DOM. But that’s no problem. We can always create a fake SearchView function to act as a stand in for testing purposes.

The key here is that even if I build a very complex application with a lot of interaction, it is only the thin view layer that is depending on the browser DOM. The rest of the code is pure JavaScript.

Testing the code (on the Windows platform)

So I have A LOT of JavaScript code to test, and it does not depend on the browser DOM, so why would I need a browser to test the code ? Wouldn’t it be much better to run the tests thru a command line JavaScript interpreter? Or even better, have the tests run inside Visual Studio ? I definitely think so. Opening up a browser to run a unit  test is way too much friction for me.

There is a JavaScript interpreter build into Windows. You can run it thru the cscript command line tool. To run a file, you do the following:

cscript myFile.js

Obviously if you are doing any meaningful testing you need to load multiple files into the environment, the testing framework, the tests, and the system under test. Luckily you can run multiple files at the same time by creating an xml file. Let's call the file test.wsf.

<?xml version="1.0" encoding="utf-8" ?>
<package>
   <job id="1">
     <script language="JScript" src="TestGui.js" />
     <script language="JScript" src="TestRunner.js" />
     <script language="JScript" src="Foo.js" />
     <script language="JScript" src="FooTests.js" />
   </job>
</package>

You can now run all the files

cscript test.wsf

We can now use this command line tool inside Visual Studio by creating an “external tool”

Tools -> External tools

image

By adding a shortcut to the external tool, I can run my JavaScript tests from anywhere in the Solution, only using a single keystroke. AND IT’S FAST!

The test runner / framework

As I mentioned previously, most JavaScript testing frameworks out there are tightly coupled to the browser DOM. That will not fly when you are using the Windows Script Host. I chose to build my own little test framework to run the tests. It is very small, and only have three method calls that are coupled to the environment it is running in.

//write to console
WScript.Echo(s); 	
...	
//quit application with error (which will break the build on TeamCity)
WScript.Application.Quit(1);	
...
//write to StdErr
WScript.StdErr.WriteLine(s);    

As you might tell from the code sample above, I run these tests on our CI server as well. No problem there.

My home-made testing framework is in an early stage. You can look at it if you want to, but don’t expect too much: http://github.com/BjartN/BigUnit.

Well, that’s it for now.  Later.

F Share