Skip to content

Running Jasmine Tests Hosted in IIS Express as part of a TeamCity Build

March 29, 2013

This week I’ve been having a lot of fun setting up a CI server for our project. I went with TeamCity as it’s a great product and there’s oodles of documentation out there so setting things up is a doddle. I chose to set up our server on a Windows Azure virtual machine, there’s a guide here on how to get started if you’re interested:

I promptly set about creating a configuration that would run all my unit tests, but ran into a small problem when it came to the JavaScript side of things.

I’d designed my test project to re-use the bundle config from my web app, and then used MVC to render the test runner. I thought I had been very clever… I had the benefit of picking up new source files as and when I created them; no need to constantly add references to new scripts in the test project.

When I came to run these tests as part of my TeamCity build process however, I realised that I needed to compile and host my tests in order to run them… not something that is easily achieveable as part of a normal build process. We don’t always know where our code will be checked out to, and we may need to do this in a way that will work for multiple configurations.

Not to worry though, with a bit of coding, we can make this work.

spc

The requirements

Our chain of events needs to run as follows:

  • Build the test project
  • Start IIS Express to host the tests
  • Run the tests and capture the results
  • Shut down IIS Express
spc

Seems simple enough. Dan Merino has a great post on how to use the jasmine team city reporter in conjunction with Phantom.JS to run our tests and process the results:

It’s also pretty easy to run IIS express from the command line (of course you’ll need to have iis express installed on your build server first):

Where it all comes unstuck however, is that we need to start IIS express after we’ve built our code, but before running our tests. Then we need to stop it again after our tests have run. There’s no built in way to do this with team city however, we need to script this in some way or write an app to help us.

spc

Phantom Express
First we need to configure a runner in our test project that will output the results in a form that TeamCity can interpret, we can do this using the TeamCity reporter:

<html>
<head>
    <title>Jasmine Spec Runner</title>

    <link rel="shortcut icon" type="image/png" href="/Content/jasmine/jasmine_favicon.png">
    <link rel="stylesheet" type="text/css" href="/Content/jasmine/jasmine.css">

    @Html.Partial("TestIncludes");

    <script type="text/javascript">
        (function () {

            var jasmineEnv = jasmine.getEnv();
            jasmineEnv.updateInterval = 1000;

            var teamCityReporter = new jasmine.TeamcityReporter();

            jasmineEnv.addReporter(teamCityReporter);
            var currentWindowOnload = window.onload;

            window.onload = function () {
                if (currentWindowOnload) {
                    currentWindowOnload();
                }
                execJasmine();
            };

            function execJasmine() {
                jasmineEnv.execute();
            }

        })();
    </script>

</head>

<body>
</body>
</html>

Secondly, we need a control file for phantom.js that will load our runner. Here’s one based on Dan’s example that will run our tests and pipe the console output:

    console.log('Loading a web page');
    var page = new WebPage();
    var url = "http://localhost:8080/tests/teamcityrunner";
    phantom.viewportSize = {width: 800, height: 600};

    //This is required because PhantomJS sandboxes the website and it does not show up the console messages form that page by default
    page.onConsoleMessage = function (msg) { console.log(msg); };

    //Open the website
    page.open(url, function (status) {

        //Page is loaded!
        if (status !== 'success') {
            console.log('Unable to load the address!');
        } else {
            //Using a delay to make sure the JavaScript is executed in the browser
            window.setTimeout(function () {
                page.render("output.png");
                phantom.exit();
            }, 1000);
        }
    });
spc

I wrote a quick command line app that will do the rest for us. All we need to do is supply it with the location of the iisexpress executable, the test site root, port, location of phantomjs and the control js file. Just make sure that you provide an appropriate timeout in the control.js file so that your tests have time to run before phantom.js closes.

I’ve copied the code for the console app into a gist as it was too long to post here: https://gist.github.com/Roysvork/5274142, you just need to compile this and copy it to your build server.

spc

Finally, here’s a snapshot of the resulting configuration in Team City:

phantomexpress

Now when we run our build, phantom express will fire up iis express, run our tests and voila!

testresults

Now you can utilise all the benefits of MVC (or any other aspect of .net) to include files and specs for your Javascript unit test suite and render your test runner. Not bad!

spc

Pete

spc

References:

Advertisements

From → TeamCity

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: