Integrating Javascript Unit Tests with Visual Studio Wrapping Up

Welcome to the grand finale of this four part series. So far you’ve got your javascript unit tests, you’ve got them all nicely organized and indexed using the info from the previous post, now how do I get to see those results when I’m inside Visual Studio? For that last cherry on the pie we’re going to use a browser automation tool walled Watin and a data-driven unit test in C#. This was borrowed from another blog and tweaked to use the XML indexing trick.

First things first, setting up your data driven unit test. If you are not familiar, this is a unit test in MSTest that you can pass in a dataset have rerun against all the values in that dataset. Here, our “dataset” is going to be the results of our javascript unit tests. In the class initialize of our unit test we go out and download the xml data that holds the location of all our test pages. From there, we use Watin to visit each page and parse out the results of each test. Because our unit tests run when a browser hits the test page, this is all we need to do run our unit tests. One thing you may need to tweak is the Watin dll has needs a reference to Interop.SHDocVw.dll, if you get errors loading that DLL, check it’s properties in your project reference and make sure that Embed Interop is false and Copy Local is true

Then we’re going to add a single test file called JavaScriptTests.cs to our unit test project. In the class initialize we’re going to setup the code that downloads our xml test index and parses out each test page’s results

    private static string _baseUrl = "http://localhost:8000/Test/";
    private static IE _ie;

    public static void ClassInit(TestContext context)
        var xdoc = XDocument.Load(_baseUrl + "?notransform");
        _ie = new IE();

        var resultsDoc = new XDocument(new XElement("Rows"));
        foreach (var testPage in xdoc.Descendants("Row"))
            _ie.GoTo(_baseUrl + testPage.Descendants("TestPageUrl").First().Value);
            var results = _ie.ElementsWithTag("li").Filter(x => x.Parent.Id == "qunit-tests");
            var xResults = from r in results
                           select new XElement("Row",
                               new XElement("name", GetTestName(r)),
                               new XElement("result", r.ClassName),
                               new XElement("summary", r.OuterText));

Quick summary, we load the xml index into a XDocument, parse each url, use Watin to load the page, and scrape out the result for each test on the page. This is all added to a separate XDocument and saved in the local test run folder as JavascriptTests.xml. This will be the dataset that gets passed into our data driven unit test and ends up looking something like this:

<?xml version="1.0" encoding="utf-8"?>
    <name>My First Tests_FullNameTest</name>
    <summary>My First Tests: FullNameTest (0, 1, 1)Rerun
full name built properlyExpected: "Nick Olson"</summary>
    <name>My First Tests_capitalizeTest</name>
    <summary>My First Tests: capitalizeTest (0, 1, 1)Rerun
capitalize worksExpected: "OLSON"</summary>
    <name>My Second Tests_FullNameTest</name>
    <summary>My Second Tests: FullNameTest (0, 1, 1)Rerun
full name built properlyExpected: "Brian Olson"</summary>
    <name>My Second Tests_FullNameFailTest</name>
    <summary>My Second Tests: FullNameFailTest (1, 0, 1)Rerun
full name built properlyExpected: "Brian Olson"
Result: "Nick Olson"
Diff: "Brian "Nick  Olson" </summary>

This is the aggregated test results for both of our test pages. The last little bit is a simple data driven unit test that takes this xml file and basically just asserts on the result element of each Row in the xml document

    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\\JavascriptTests.xml", "Row", DataAccessMethod.Sequential), TestMethod]
    public void JavascriptTestRunner()
        var testName = TestContext.DataRow["name"].ToString();
        var testResult = TestContext.DataRow["result"].ToString();
        var summary = TestContext.DataRow["summary"].ToString();

        TestContext.WriteLine("Testing {0} - {1}", testName,testResult);
        if (testResult != "pass")
            Assert.Fail("{0} failed: {1}", testName,summary);

That’s it! You’re all done. Now when you run your tests in Visual Studio, it will run all the C# unit tests, including your new data driven javascript test and aggregate all these into your normal Test Results window. If you looked at my sample code you may have noticed that I have a failing test in javascript. If I run my tests in Visual Studio you can it sitting, failed, next to some C# unit tests, but it only tells me my data driven test failed, no other info

But if we click on that test it will open up a detail window and give us the results for every record in the data set for that data driven test, which is a lot nicer

Double clicking on that will give us even more detail yet

So there you go, test in the browser, test in Visual Studio it’s up to you. Generally I like to work on the html test page while I’m working and writing my tests and let the MSTest integration work for me on a build server or something else when the tests are run.

Here is the complete little sample app,

12 thoughts on “Integrating Javascript Unit Tests with Visual Studio Wrapping Up

  1. Yanira

    A motivating discussion is definitely worth comment.

    I do believe that you should publish more about this issue, it may
    not be a taboo matter but generally folks don’t discuss such issues.
    To the next! Kind regards!!

  2. 逆向网赚




Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>