Skip to content

Functional (unit) testing

Martin Doyle edited this page Feb 1, 2016 · 7 revisions

Background Information

Aikau uses Intern for functional/unit testing of its components. Aikau provides the capability for testing locally; against a Vagrant VM on Firefox and Chrome; and against BrowserStack on multiple browsers. We use node-coverage for collecting test coverage data.

Preparing the environment for testing

For all testing

Regardless of where the tests are run, you will need to have grunt-cli and npm installed globally. Then you will need to run npm install within Aikau/aikau. Once this has been done, and before running tests, you need to start the test server, which can be done by running mvn clean install jetty:run.

Setting up Vagrant

You can create the Vagrant VM by running (the force may be optional ... some people say they need it):

grunt vcreate --force

Setting up BrowserStack

If you have your own BrowserStack account and want to run tests against BrowserStack, then you will need to setup two environment variables (BROWSERSTACK_ACCESS_KEY and BROWSERSTACK_USERNAME) as per your credentials. Also, you will need to install the local Browserstack tunnel on your machine.

Running Tests

All tests are run through grunt, so you should run grunt <target> where target is one of test, test_local or test_bs for vagrant tests, local tests and Browserstack tests respectively. To generate code coverage results run grunt vm-coverage-report.

Writing Tests

Basics

Test files are located in the aikau/src/test/resources/alfresco/creation folder and the test files are organized into a directory structure that matches the source structure (e.g the test tests for the "alfresco/menus" widgets are located in the "alfresco/menus" directory within the test file location.

Each test file will contain one or more test suite and every test file should be referenced in the suites.js file.

Each test suite should load a specific test page that is represented by an individual WebScript.

Test Suite Structure

A test suite should have the following basic structure:

/**
 * Copyright (C) 2005-2015 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * <test description>
 * 
 * @author <test author name>
 */
define(["intern!object",
        "intern/chai!assert",
        "require",
        "alfresco/TestCommon",
        "intern/dojo/node!leadfoot/keys"],
        function(registerSuite, assert, require, TestCommon, keys) {
   var browser;
   registerSuite({
      name: "<test suite name>",
      setup: function() {
         browser = this.remote;
         return TestCommon.loadTestWebScript(this.remote, "/<test page url>", "<test suite name>")
            .end();
      },
      beforeEach: function() {
         browser.end();
      },
      
      // TESTS START HERE...
      "<test name>": function() {
         // TEST GOES HERE
      },

      // MORE TESTS...

      // FINALLY...
      "Post Coverage Results": function() {
         TestCommon.alfPostCoverageResults(this, browser);
      }
   });
});

Test Structure

Each test should have a meaningful name (e.g. "Test that X happens when we do Y") and should ideally only have a single assertion. Try to avoid sleeps if possible as this is often an indication that your test is badly written.

All the tests will be promise based and you will need to use the Leadfoot WebDriver commands. The tests will be functional in style and guidance on writing functional Intern tests can be found here.

Test Page WebScripts

The controller of the WebScript for a test page should have the following structure:

model.jsonModel = {
   services: [
      // ADD REQUIRED SERVICES HERE
   ],
   widgets:[
      // ADD WIDGETS TO BE TESTED HERE...
      {
         name: "alfresco/logging/SubscriptionLog"
      },
      {
         name: "aikauTesting/TestCoverageResults"
      }
   ]
};

It is essential that both the alfresco/logging/SubscriptionLog and aikauTesting/TestCoverageResults widgets be included on the test page.

What to test

Ideally we're looking to achieve 80% or more statement coverage. A widget or service should be an atomic unit that is driven by publications and outputs publications and should be testable as such. Publications can easily be generated through the use of the alfresco/buttons/AlfButton widget and publication output can be captured by the alfresco/logging/SubscriptionLog widget.

TestCommon.js

A helper module called alfresco/TestCommon has been provided to assist with writing tests. In particular this provides helper functions for determining that the expected publications have been made and that those publications contain the expected payload data.