Running JavaScript unit tests headlessly in a Continuous Integration build Running JavaScript unit tests headlessly in a Continuous Integration build javascript javascript

Running JavaScript unit tests headlessly in a Continuous Integration build


As I managed to come up with a solution myself, I thought it would be a good idea to share it. The approach might not be flawless, but it's the first one that seemed to work. Feel free to post improvements and suggestions.

What I did in a nutshell:

  • Launch an instance of Xvfb, a virtual framebuffer
  • Using JsTestDriver:
    • launch an instance of Firefox into the virtual framebuffer (headlessly)
    • capture the Firefox instance and run the test suite
    • generate JUnit-compliant test results .XML
  • Use Bamboo to inspect the results file to pass or fail the build

I will next go through the more detailed phases. This is what my my directory structure ended up looking like:

lib/    JsTestDriver.jartest/    qunit/            equiv.js            QUnitAdapter.js    jsTestDriver.conf    run_js_tests.sh    tests.jstest-reports/build.xml

On the build server:

  • Install Xvfb (apt-get install Xvfb)
  • Install Firefox (apt-get install firefox)

Into your application to be built:

server: http://localhost:4224load:# Load QUnit adapters (may be omitted if QUnit is not used)  - qunit/equiv.js  - qunit/QUnitAdapter.js   # Tests themselves (you'll want to add more files)  - tests.js

Create a script file for running the unit tests and generating test results (example in Bash, run_js_tests.sh):

#!/bin/bash# directory to write output XML (if this doesn't exist, the results will not be generated!)OUTPUT_DIR="../test-reports"mkdir $OUTPUT_DIRXVFB=`which Xvfb`if [ "$?" -eq 1 ];then    echo "Xvfb not found."    exit 1fiFIREFOX=`which firefox`if [ "$?" -eq 1 ];then    echo "Firefox not found."    exit 1fi$XVFB :99 -ac &    # launch virtual framebuffer into the backgroundPID_XVFB="$!"      # take the process IDexport DISPLAY=:99 # set display to use that of the xvfb# run the testsjava -jar ../lib/JsTestDriver.jar --config jsTestDriver.conf --port 4224 --browser $FIREFOX --tests all --testOutput $OUTPUT_DIRkill $PID_XVFB     # shut down xvfb (firefox will shut down cleanly by JsTestDriver)echo "Done."

Create an Ant target that calls the script:

<target name="test">            <exec executable="cmd" osfamily="windows">        <!-- This might contain something different in a Windows environment -->    </exec>    <exec executable="/bin/bash" dir="test" osfamily="unix">        <arg value="run_js_tests.sh" />    </exec></target>   

Finally, tell the Bamboo build plan to both invoke the test target and look for JUnit test results. Here the default "**/test-reports/*.xml" will do fine.


For anyone interested in running their Jasmine BDD specs headlessly in maven, you might be interested in the jasmine-maven-plugin I maintain:

http://github.com/searls/jasmine-maven-plugin


As an alternative, you could also try TestSwarm. I've got it up and running using QUnit to run my JS tests.