QUnit layout for JavaScript testing in ASP.net MVC3

On December 8, 2011, in JavaScript, by jonathancreamer

Testing JavaScript is something that a lot of people say they want to do, but never really get around to doing.

Why Not?!?

It’s extremely important stuff since JS is what the All-Important-User sees, especially these days with so much Javascript code being punched out.

One of the many testing frameworks out there is called QUnit and was written by the jQuery team to test jQuery. It has a very straightforward API, and is quite easy to use. The basic idea is this…

// calculator.js
var Calculator = function(){};

Calculator.prototype.add = function(x,y){
    return x + y;
}

// calculator_tests.js
module("A group of tests get's a module");
test("First set of tests", function(){
    var calc = new Calculator();
    ok(calc, "My caluculator is a O.K.")
    equals(calc.add(2,2), 4, "If this doesn't equal 4, the laws of the universe will be broken");
});

 

The module  just defines a set of tests, then each test in that module is defined with a name and a function callback to run the test. The two basic assertion functions in QUnit are ok(value, [successMessage]) and equals(actual, expected, [successMessage]).

The are also, notEqual, deepEqual, notDeepEqual, strictEqual, notStrictEqual, and raises.

The other piece needed to render the QUnit test looks like this.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/content/css/qunit.css" />
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
    <script src="/scripts/qunit.js"></script>
    <script src="/scripts/calculator.js"></script>
    <script src="/scripts/calculator_tests.js"></script>

</head>
<body>
    <h1 id="qunit-header">QUnit Tests</h1>
    <h2 id="qunit-banner"></h2>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests">
    </ol>
</body>
</html>

 

Below is a an easy way to share certain pieces of the tests layout in an ASP.net MVC3 application.

First create a Tests Controller. Each action method will correspond to different tests.

public class TestsController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Calculator()
    {
        return View();
    }
}

Then in the /Views/Tests folder you’ll create your views. The Index view I put a little voodoo in…

<ul>
@{
    var controller = ViewContext.Controller.GetType();
    var methods = controller.GetMethods()
        .Where(m => m.ReturnType.ToString() == "System.Web.Mvc.ActionResult");

    foreach(var method in methods)
    {
        <li>@Html.ActionLink(@method.Name, @method.Name, "Tests")</li>
    }
}
</ul>

This will render out a bulleted list with links to all of the tests you have in your TestsController. That way you’ll be able to go to Tests/ and see all of the tests in your application.

The next thing is to create Views/Tests/_ViewStart.cshtml

@{
    Layout = "_TestsLayout.cshtml";
}

And then for the Views/Tests/_TestsLayout.cshtml

<!DOCTYPE html>

<html>
    <head>
        <title>@ViewBag.Title</title>
        <link rel="stylesheet" href="/content/css/qunit.css" />
        <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script src="/scripts/qunit.js"></script>

        @RenderSection("Javascript", false)
    </head>
    <body>
        @RenderBody()
    </body>
</html>

And each view will look like this…

@{
    ViewBag.Title = "Home Tests";
}

@section Javascript{
    <script src="/scripts/calculator.js"></script>
    <script src="/scripts/calculator_tests.js"></script>
}

@Html.Partial("_QUnit")

And last but not least the _Qunit.cshtml partial view

<h2>@ViewBag.Title</h2>

<h1 id="qunit-header">QUnit example</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests">
</ol>

@Html.ActionLink("Back to Tests", "Index", "Tests")

Now all you have to do to create a new test is…

  1. Create the JS and JS_Tests files
  2. Add an Action Method to the Tests Controller
  3. Add a new View for the Method
  4. Change the JS references in the Javascript section

P.S. Checkout MockJax for mocking Ajax requests

Tagged with:  
  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #998

  • http://www.johncoder.com/ John Nelson

    There has been a lot of interest in trying to maintain javascript tests from an MVC project recently. I’ve seen some cool ideas. I experimented with automating QUnit in an MVC test project a little over a year ago.

    https://bitbucket.org/johncoder/mvcqunit/overview

    Basically it did some “voodoo magic” and redirects through an automatically generated list of test pages, running the tests and reporting the data back to the server. I lost some interest in it, but it was pretty cool to open a browser and click “go!” and watch it go through and run my full suite of tests automatically in the browser.

  • Sam Stephens

    I’m thinking that for the project I’m currently involved, we have an NUnit/Selenium test harness. So it would be trivial to add a test to the test harness that pointed at the index page, scraped the URLs to the test actions, and then visited each of the test URLs checking the result. Meaning we can check our QUnit tests as part of our CI builds. Nice!

    Is there a simple way to do this I’m missing, or would you see this as a typical way to automate QUnit testing?

  • Pingback: Using QUnit with Razor Layouts

  • http://www.rapidsofttechnologies.com/asp.net-application-development.html Burton Taylor

    The code given in the article really helped me. Thanks for sharing.

  • slev kalevre

    sounds good. thanks for sharing. I will try …

  • Pingback: Javascript unit testing with QUnit « raulamedey

  • Pingback: PongR part 3: client side | thewayofcode