Skip to Content
Author's profile photo Ido Goren

Automating Headless JavaScript Unit Tests

Hi Everyone,

I would like to share my experiences of automating our JavaScript unit tests.

My name is Ido Goren and I’m a member in the River development team.

Our team develops mainly in JavaScript. After considering several options, I chose to base our unit tests on the QUnit framework.

In short, QUnit provides a set of assertion functions, that when run from within a test can cause the test to fail. To run your tests, you write a very simple HTML file that when opened in a browser window, launches the tests and displays their results.

In order to ensure the quality of our product, I wanted to run our unit tests as part of our central build process (a Jenkins job running on a Linux machine in Germany) that is triggered every time a developer submits code to our source control (git in our case). However, running QUnit tests requires a browser, which is quite challenging for a central build machine that runs headlessly (meaning with no user interface). It would require us to configure the Linux machine to run X Window System, but we have no control over that machine…

It turns out that a framework called PhantomJS can do the trick. It’s not a test framework, but can run tests heedlessly and is used by many open source projects to test their products. You simply download the native executable from the website and runs it with a JavaScript file as a parameter. This JavaScript file, commonly called a runner script, uses PhantomJS API functions to in turn run the QUnit html test files. To run your tests headlessly run the following line from the command line:

<path to your PhantomJS exe file>/phantomjs.exe <your runner file> <your html test file>

You could even pipe the result to an xml file that’s compatible with the JUnit test output format.

In the process of adapting our code to run using PhantomJS, I found it useful to separate testing logic from the test HTML file.

One challenge that I faced here was dealing with asynchronous JavaScript function call sequences. Asynchronous functions are part of our product, since we use JQuery Ajax functions, Q deferred calls and RequireJS. Therefore, I needed to ensure that the PhantomJS executable didn’t exit before the test results were ready. I resolved this issue with the help of our colleague Yotam Shapira from NetWeaver Portal that provided me with a runner script that handles asynchronous JavaScript functions.

Even though we don’t actually compile our client-side JavaScript files, we depend on a central build server for performing several tasks. These tasks include running static code checks (using JSHint), running unit tests, packaging our code into HANA delivery units and deploying them to different servers. We use Maven for the first 2 tasks: running static code checks and running unit tests. One of the advantages of using Maven is that developers can run the tests locally, directly from within their development environment, before submitting their code.

Therefore, my final challenge was finding a Maven plugin that could run PhantomJS. I used our internal Nexus server to find the the phantomjs-maven Maven plugin.

I hope you’ll find this information useful and any feedback will be more than welcome!



Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.