Skip to content

Fast JavaScript Integration Tests

tntim96 edited this page Dec 7, 2015 · 3 revisions

Fast JavaScript Integration Tests

Definition

This article defines a JavaScript integration test as a test that integrates with the generated DOM and JSON of an application. It is quick because the tests can be run on the file-system (or a simple web-server). AJAX calls are mocked and are not tested end-to-end, however the mock data is generated and allows valid assertions to be made.

Introduction

This is a topic I haven't seen covered elsewhere, so have decided to write a quick piece on how this technique is useful as part of a web-application development process. I'm interested in any feed-back to improve this article.

The strategy is to use:

  • existing application code to generate static web-pages that will run JavaScript tests
  • JavaScript, typically jQuery and jQuery Simulate, to generate synthetic events to simulate user interaction
  • web-browser automation to run the test, check results and store coverage results
  • JSCover to collect coverage

I've used this approach with Java tools and template technologies to achieve greater than 90% code coverage in a matter of seconds - and that 90% can be quickly tested across multiple browsers.

The technique is slower than pure JavaScript tests run on NodeJS, however it does test more and is much quicker than testing JavaScript on a running application server.

Benefits:

  • UI development can largely be done without ever starting the application server
  • UI tests can be executed much more quickly than on a running application server
  • Tests not only JavaScript, but it's interaction with the DOM and generated JSON
  • Easily added to your build as part of continuous integration
  • Can easily test in multiple browsers

Drawbacks:

Generating and running the tests

The process outlined:

  1. Generate the HTML
    1. Use domain objects to populate your model, then render your view HTML
    2. Alter the view HTML to load static files if necessary (you may need to change your paths)
    3. Save the view HTML fo the file-system
    4. At this point, you can open the HTML file in a browser to verify that it is rendered correctly
  2. Write your JavaScript tests
    1. Write a simple JavaScript test
    2. Alter the view HTML to load the test framework and your test
    3. To simulate AJAX calls, you can:
      1. Use your JSON tool (e.g. Jackson) to convert server-side model objects into a meta-tag
      2. Write AJAX intercept calls to retrieve the contents from your generated meta-tag
  3. Write your JavaScript test runner
    1. Use your language of choice to:
      1. Start JSCover to measure code coverage and serve the static content
      2. Run the browser automation tool of choice to loop over each generated file to run the tests
      3. Save the coverage results

Tips

Testing different versions of IE Emulation

If you are automating with WebDriver, testing in different browsers is a simple matter of configuration.

Testing in IE usually requires testing in multiple versions of IE. While this can be done using a VM (and this is recommended) many IE version specific bugs can be found using emulation. As part of the test process, the following can be added to the generated HTML to test in, for example, IE8 emulation mode.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8"/>

Sample Generated Meta-Tag for AJAX

<meta name="getDataJson1" content="{&quot;data&quot;:{&quot;id&quot;:1}}"/>

Sample AJAX Intercept Code

var ajaxRequests = [];
$(document).ready(function () {
  $.ajax = function (params) {
    ajaxRequests.push(params);
    var jsonString, match;
    //console.log(params.url);
    match = params.url.match(/\/data\/([^\/]*)\/getData.json$/);
    if (match) {
      jsonString = $("meta[name=getDataJson" + match[1] + "]").attr("content");
      //console.log(jsonString);
      //try {
      params.success(JSON.parse(jsonString));
      //}
      //catch(e) {}
      return;
    }
  };
});