Skip to content

Functional and unit testing

Stephen A Thomas edited this page Aug 5, 2015 · 13 revisions

The OAE functional and unit tests were created to avoid regressions and increase speed of development.

Prerequisites

The OAE installation notes provide a complete guide to setting up a development environment. If you are looking to run the functional and unit tests you'll need to complete these steps to be able to proceed.

QUnit

QUnit is a powerful, easy-to-use JavaScript unit testing framework. It is capable of testing any generic JavaScript code. We use QUnit to execute a variety of test suites. They can be executed in the browser or in your favourite terminal client. Our tests include:

  • Core
    • Clean JavaScript
  • Internationalization and localization
    • Unused Translation Keys
    • Untranslated Translation Keys
    • Double Translation Keys
    • Uninternationalized English Strings
  • Formatting
    • CSS Formatting
    • JavaScript Formatting
  • Accessibility
    • WCAG 2.0 Compliance - 1.1.1 Non-text Content / Text Alternatives
Installation

Installing QUnit and its dependencies is as simple as running npm install -d in the 3akai-ux repository you cloned to your local machine when following the OAE installation notes.

The OAE uses GruntJS to automate certain tasks like minification, compilation and unit testing. Grunt takes care of the repetitive work that comes with running tasks like this. Grunt will also be installed when executing npm install -d.

Running the QUnit tests

Once the npm install -d command finishes successfully QUnit can be run through terminal by executing grunt qunit:tenant1.oae.com where tenant1.oae.com needs to be replaced with a running tenant. If you prefer a more graphical interface you can visit http://tenant1.oae.com/tests (replace tenant1.oae.com with a running tenant) to see a hub from which you can run the tests.

An example of the terminal output: grunt qunit:cam.oae.com terminal output

An example of the browser output: 'QUnit browser output'

CasperJS

CasperJS is an open source navigation scripting & testing utility written in Javascript for the PhantomJS WebKit headless browser and SlimerJS (Gecko). It eases the process of defining a full navigation scenario and provides useful high-level functions, methods & syntactic sugar for doing common tasks.

The OAE uses CasperJS to test widgets and scenarios. A single test lives completely separate from other tests in a sense that it's not reusing any data created by other tests. The reason for making this as modular as possible is to avoid data from tests influencing other tests. All tests have access to a shared API for user creation, content upload, log in/log out,...

Installation

As outlined on the installation page there are several ways of installing CasperJS and its dependencies. If you're on a mac Homebrew is the fastest way to get up and running. (As of this writing, you must install the development version of casperjs using brew install casperjs --devel.) We suggest following this guide for the most up to date documentation on installing CasperJS.

Check your installation by running casperjs --version and phantomjs --version. The OAE currently supports CasperJS v1.1.x and PhantomJS v1.9.x.

CasperJS will execute all tests on a new tenant test.oae.com. For the tenant to be available you will have to add test.oae.com to your hosts file.

As with the QUnit tests you will need to run npm install -d in the 3akai-ux repository to install any other dependencies that drive CasperJS. Grunt uses the grunt-casperjs module to run tests and tries to install CasperJS if it has not been detected on your machine. The module is suffering from a bug where it fails to install CasperJS so it is advised to install CasperJS before running npm install -d.

Running the CasperJS tests

Once CasperJS has been installed, npm install -d completes successfully and you added the test tenant to your hosts file you are ready to run the tests by executing grunt ghost in the 3akai-ux directory.

An example of the terminal output: grunt ghost terminal output

Running an individual test

You can also run an individual test to save time when developing a widget.

grunt test-file --path=path/to/test.js
Write your own tests

You can easily write your own tests in the existing framework. CasperJS looks for tests in admin/tests/* and node_modules/oae-core/*/tests/. If new files are added to those directories they automatically get picked up.

The template below contains the basics for every test in the OAE.

  • casper.test.comment() prints the title of the test in the terminal.
  • casper.start() will start the headless webkit browser and point it to the specified page.
    • Every test creates its own users to test with (keeps things separated).
    • casper.then() adds a navigation step to the test.
      • casper.echo() prints the title of the navigation step in the terminal
      • executeFirstTestBlock calls the test block function. We use separate functions for maintainability and readability.
    • At the end of every test the user needs to log out to prepare for the next test.
  • The casper.run() callback will instruct CasperJS to start the next test when this one finishes.
casper.test.comment('Widget - My first CasperJS test');

/**
 * Execute the first test block
 */
var executeFirstTestBlock = function() {};

/**
 * Starts the browser and points it to the landing page.
 */
casper.start('http://test.oae.com/', function() {
    // Create a user to test with
    var user = null;
    userUtil().createUsers(1, function(users) {
        user = users[0];
    });

    // Login with that user
    casper.then(function() {
        userUtil().doLogIn(user.username, 'password');
    });

    // Execute a first test block
    casper.then(function() {
        casper.echo('Execute a first test block', 'INFO');
        executeFirstTestBlock();
    });

    // Log out at the end of the test
    casper.then(function() {
        userUtil().doLogOut();
    });
});

casper.run(function() {
    this.test.done();
});

The name you give to the file containing your test is irrelevant to the test itself. For consistency sake the tests for widgets get the ID of the widget as a name. Other tests get a descriptive name (e.g. login.js).

Run QUnit and CasperJS together

It's possible to run QUnit and CasperJS together in one command by doing grunt test --qunit-host tenant1.oae.com where tenant1.oae.com needs to be replaced by a running tenant.

This will run the CasperJS tests first followed by the QUnit tests (we use this on Travis CI).

FAQ

I'm getting a >> PhantomJS timed out, possibly due to a missing QUnit start() call. failure and my tests won't run.

  • Do you have PhantomJS installed? phantomjs --version
  • Did you specify an existing tenant when running the tests? grunt test --qunit-host tenant1.oae.com or grunt qunit:tenant1.oae.com