.

Tags:

What Github does to project repository and collaboration, Travis CI does it to continuous integration. If you have an open-source project, there is a huge chance that you can benefit a lot from hooking your testing via Travis CI. As of now, it supports projects using Clojure, Erlang, Groovy, Java, Node.js, Perl, PHP, Python, Ruby, Scala and I’m sure the list will continue to grow.

What if your project is a web application? PhantomJS to the rescue! I already wrote about using PhantomJS to drive your tests as part of the preflight check via Git pre-commit hook. The same technique applies here. In fact, there are few projects using Travis CI which already use the approach, mainly because Travis CI has built-in install of PhantomJS.

To see how to set it up, let’s have a look at one project: Modernizr . Its .travis.yml (see the repository, as of now in the travis-ci branch) looks like the following:

language: node_js
node_js:
  - 0.6
before_script:
  - "export DISPLAY=:99.0" 
  - "sh -e /etc/init.d/xvfb start"
  - npm install connect
  - sudo node test/js/server.js ../../ 80 &
  - sleep 5
script: phantomjs test/qunit/run-qunit.js "http://localhost:80/test/index.html"

Per Travis CI documentation, the before_script is the prep stage. It is actually very simple: start Xvfb (important for now, not necessary anymore in the next version), launch the server (Node.js-based) which provides the tests, wait 5 seconds. After that, the actual magic kicks in, i.e. running PhantomJS to drive the QUnit-based test suite. Isn’t it really simple?

Update: Travis CI has updated its PhantomJS installation to the latest version 1.5 (Ghost Flower) which is pure headless and does not need X anymore. This means, there is no need to execute Xvfb nor to set up DISPLAY.

Of course, you don’t have to use Node.js to launch your test server. Take a look at how Ember.js uses PhantomJS in its Travis CI setup (it just launches Ruby-based Rack):

rvm:
  - 1.9.3
before_script:
  - "export DISPLAY=:99.0"
  - "sh -e /etc/init.d/xvfb start"
  - bundle exec rackup &
  - sleep 5
script: phantomjs tests/qunit/run-qunit.js "http://localhost:9292/tests/index.html?package=all" &&
phantomjs tests/qunit/run-qunit.js "http://localhost:9292/tests/index.html?package=all&jquery=1.6.4" &&
phantomjs tests/qunit/run-qunit.js "http://localhost:9292/tests/index.html?package=all&extendprototypes=true" &&
phantomjs tests/qunit/run-qunit.js "http://localhost:9292/tests/index.html?package=all&extendprototypes=true&jquery=1.6.4"

Last but not least, there is no need to use a web server if you don’t need to. CasperJS simply uses PhantomJS to execute the test suite directly (BTW, in case you haven’t seen CasperJS yet, go and take a look, it’s an extremely useful companion to PhantomJS):

branches:
  only:
    - master
before_script:
  - "export PHANTOMJS_EXECUTABLE='phantomjs --local-to-remote-url-access=yes --ignore-ssl-errors=yes'"
  - "export DISPLAY=:99.0"
  - "sh -e /etc/init.d/xvfb start"
script:
  - "DISPLAY=:99.0 ./bin/casperjs test tests/suites"

With popular projects such as Modernizr, Ember.js, and CasperJS taking advantage of the (dangerous) combination of PhantomJS and Travis CI, what are you waiting for?