I’ve been investigating different unit testing frameworks for JavaScript lately and I stumbled onto FireUnit. FireUnit is a unit testing framework created by John Resig (of well-deserved jQuery fame) and Jan Odvarko. In this blog entry, I provide a brief overview of the FireUnit testing framework. In particular, I explain how you can use FireUnit to unit test JavaScript code.

Installing FireUnit

FireUnit is implemented as a FireFox extension. This is both bad and good. First, the bad news. You cannot use FireUnit with Internet Explorer, Safari, Chrome, or any other browser than Mozilla Firefox.

Here’s the good news. FireUnit extends Firefox with a new Test tab. This Test tab appears as an extra Firebug tab. Therefore, seeing test results is very convenient.

Before you can use FireUnit, you need to first install the Firebug extension for Firefox. If you haven’t already installed Firebug then you should be ashamed of yourself. Every JavaScript developer is required, by law, to have Firebug installed. You can learn about Firebug by visiting http://Firebug.org. the easiest way to install Firebug is to select the menu option Tools, Add-ons within Firefox, select the Get Add-ons tab and enter Firebug in the search box (see Figure 1).

Figure 1 – Adding Firebug

clip_image002

After you install Firebug, you can install FireUnit. Navigate to the following website within Firefox:

http://FireUnit.org

After you install FireUnit, a new Test tab appears when you open Firebug (see Figure 2). Your FireUnit test results appear in this tab. Figure 2 depicts what happens when two tests pass and one test fails.

Figure 2 – Viewing test results

clip_image004

Making Assertions in FireUnit

Documentation on FireUnit is very limited. To learn what methods are available, I downloaded the source for FireUnit and looked at the functions defined in the fireunit.js file (this file includes some helpful comments). I also used the Firebug DOM inspector and inspected the fireunit class.

Here is a list of the test assertion methods that you can call:

· ok(pass, msg, expected, actual) – Pass specifies a condition that when true causes the test to pass.

· compare(expected, actual, msg) – Compares two strings.

· reCompare(expected, result, msg) – Compares a string to a regular expression pattern. The expected parameter represents the regular expression pattern.

· testDone() – Call this method to display a summary of all of the test results.

The methods listed above are methods of the fireunit class. Notice that these are non-standard method names for a unit testing framework. You use fireunit.ok() instead of assert.AreEqual().

Listing 1 contains a MathUtility class created in JavaScript.

Listing 1 – MathUtility.js

function MathUtility() {

    this.add = function(val1, val2) {
        return val1 + val2;
    };
}

Listing 2 contains a MathUtilityTests class that contains a set of tests for the MathUtility class.

Listing 2 – MathUtilityTests.js

/// <reference path="MathUtility.js"/>

function MathUtilityTests()
{
    this.testAddPositiveNumbers = function()
    {
        // Arrange
        var mathUtility = new MathUtility();
        
        // Act
        var result = mathUtility.add(1,3);

        // Assert
        fireunit.ok(result === 4, "Test add positive numbers");        
    }

    this.testAddNegativeNumbers = function()
    {
        // Arrange
        var mathUtility = new MathUtility();

        // Act
        var result = mathUtility.add(-1,-3);

        // Assert
        fireunit.ok(result === 4, "Test add negative numbers");        
    }


    this.testAddNegativeAndPositiveNumbers = function()
    {
        // Arrange
        var mathUtility = new MathUtility();

        // Act
        var result = mathUtility.add(-1,3);

        // Assert
        fireunit.ok(result === 2, "Test add negative and positive numbers");        
    }
}

Notice that Listing 2 consists of a set of tests. The fireunit.ok() method is used to perform assertions about a particular condition (we are doing state verification here). The <reference> comment at the top of the file is used to enable Intellisense for the MathUtility class for Visual Studio/Visual Web Developer (Visual Studio JavaScript Intellisense is an amazing and useful feature).

Listing 3 consists of an HTML page that includes both the MathUtility and MathUtilityTests JavaScript files. Each of the test methods in the MathUtilityTests class is called by iterating through all of the class methods that start with the keyword test. Finally, the fireunit.testDone() method is called to display the summary of test results.

When you open the HTML page in Listing 3 in Firefox, you see the test results in Figure 2.

Listing 3 – Test1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    
    <script src="MathUtility.js" type="text/javascript"></script>
    <script src="MathUtilityTests.js" type="text/javascript"></script>

    <script type="text/javascript">

        var mathUtilityTests = new MathUtilityTests();

        // Run all tests in MathUtilityTests
        var method;
        for (method in mathUtilityTests) {
            if (method.substring(0, 4) == 'test')
                mathUtilityTests[method]();
        }

        // Display result summary
        fireunit.testDone();
    
    </script>

</head>
<body>

</body>
</html>

Figure 2 – Results of opening the Test1.html page

clip_image006

Running a Suite of Tests

According to the documentation, you should be able to run a suite of tests by using the fireunit.runTests() method like this:

if (fireunit.forceHttp()) {
    // Run all tests in AddTests.htm and SubtractTests.htm         
    fireunit.runTests("AddTests.htm", "SubtractTests.htm");
 
    // Display result summary
    fireunit.testDone();
}

In this case, the tests in the AddTests.htm and SubtractTests.htm should be run. Unfortunately, I could not get this code to work. The fireunit.forceHttp() method always returns false.

Simulating Browser Events

FireUnit overlaps, a little bit, in functionality with an acceptance testing tool such as Selenium. FireUnit includes a small set of methods for simulating browser events:

· click(node) – Simulates a click event on an HTML DOM node.

· focus(node) – Simulates a focus event on an HTML DOM node.

· id(id) – Shortcut for document.getElementById().

· key(node, letter) – Simulates a keypress event on an HTML DOM node with the specified letter.

· mouseDown(node) – Simulates a mousedown event on an HTML DOM node.

· value(node, text) – Assigns the text to the value property of an HTML DOM node.

For example, the HTML page in Listing 4 verifies that clicking a button changes the text in a <span> tag to the value Hello World!

Listing 4 – TestClick.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Test Click</title>
    
    <script type="text/javascript">

        function showHello() {
            document.getElementById('message').innerHTML = "Hello World!";
        }
    
    </script>
    
</head>
<body>

<button id="btn" onclick="showHello()">Click Here</button>
<span id="message"></span>


<script type="text/javascript">
    // Act
    fireunit.click("btn");
    var result = document.getElementById('message').innerHTML;
    
    // Assert
    fireunit.compare("Hello World!", result, "Click displays Hello World!");
    fireunit.testDone();
</script>


</body>
</html>

The fireunit.click() method simulates clicking the button in the page (see Figure 3). The test in Listing 4 uses the fireunit.compare() method to verify that the contents of the message <span> tag match the text Hello World!

Figure 3 – The fireunit.click() method causes the message to appear

clip_image008

Summary

I like the FireUnit user interface. In other words, I like the fact that your test results appear in a Firebug tab automatically. Because the interface forces you to see your test results every time you open a page, this interface enables you to make testing a natural part of developing JavaScript code.

FireUnit is still in its infancy. The framework has a very limited set of features. In particular, it is frustrating that you cannot use FireUnit with browsers other than Firefox.

If you liked this blog post then please Subscribe to this blog.
posted on Monday, May 18, 2009 9:45 AM | Filed Under [ ASP.NET JavaScript TDD ]

Comments

Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Paco
on 5/18/2009 11:39 AM

Isn't this integration testing?
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by tap
on 5/18/2009 11:42 AM

Firebug can be found at http://getfirebug.com, firbug.org is just a parked domain.
Gravatar
# re: Unit Testing JavaScript with FireUnit
on 5/18/2009 12:00 PM

Execelent!, thank for this post!
Best Regards,
Gonzalo
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Hadi Teo
on 5/18/2009 6:47 PM

There is another alternative which is WatiN http://watin.sourceforge.net/ or JsUnit http://www.jsunit.net/
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Ravzan
on 5/18/2009 11:30 PM

interesting addon. For sure it will make our js scripts more accurate.
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Jonathan young
on 5/19/2009 1:31 AM

the firefox debuggin is powerful than ie.
this is a good addon on firefox.
thanks
Gravatar
# re: Unit Testing JavaScript with FireUnit
on 5/19/2009 5:35 AM

Have you taken a look at QUnit its part of the JQuery library.

Regards,

Roberto.-

Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Stephen.Walther
on 5/19/2009 7:48 AM

@Roberto -- thanks for the reference to QUnit. I need to investigate that.
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Parag Mehta
on 5/20/2009 1:51 AM

I am getting a little cynical. Can you tell me what kind of application requires JavaScript unit testing ? What are you going to test ? Personally I don't see any benefit but open to suggestions.
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by Stephen.Walther
on 5/20/2009 7:52 AM

@parag -- that is a fair question -- especially given my unrealistic MathUtility example in the blog entry :)

Anytime that it is important that your code behave in a particular way, you should write a test for the code. Your JavaScript code might contain UI or business logic that is complicated enough that you need the extra confidence that a test provides you.

If, on the other hand, you are just using JavaScript to create cool looking hover effects, I agree that you most likely won't need to start writing tests for your JavaScript.
Gravatar
# re: Unit Testing JavaScript with FireUnit
Posted by chenpu
on 5/27/2009 2:07 AM

How to install fireunit?
Gravatar
# re: Unit Testing JavaScript with FireUnit
on 6/25/2009 11:55 PM

Excellent Post! Really Fireunit is a good Add-ons for firefox. Thanks.
Gravatar
# re: Unit Testing JavaScript with FireUnit
on 6/27/2009 1:05 AM

I'm guessing you're not a Perl programmer? Check out Test::More etc.. on CPAN. Personally I'd love to see even more of those concise test methods being used, is() for euqality, like() for regex string comparison, etc.. but as John showed it's easy to create your own test API object if you don't like their choice of method names.
Gravatar
# re: Unit Testing JavaScript with FireUnit
on 7/2/2009 9:46 PM

Well giving information about Fireunit.
Comments have been closed on this topic.