Skip to content

Functional (unit) testing

Martin Doyle edited this page May 20, 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. Coverage data is collected via Intern, although it is pre-instrumented because of the Surf build process used to concatenate the files.

Preparing the environment for testing

For all testing

You must have Node.js version 6.x or higher (we recommend using the latest version). 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 test|test_local|test_bs

... 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 coverage

Writing Tests

Basics

Test files are located in the aikau/src/test/resources 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 suites 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-2016 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(["module",
        "alfresco/defineSuite",
        "intern/chai!assert",
        "intern/dojo/node!leadfoot/keys"],
        function(module, defineSuite, assert, keys) {

   defineSuite(module, {
      name: "<name of test suite>",
      testPage: "/<test page url>",

      "<test name #1>": function() {
         // TEST GOES HERE
      },

      "<test name #2>": function() {
         // TEST GOES HERE
      }
   });
});

Test Structure

Each test should have a meaningful name (e.g. "X occurs when state is Y" or "X is true after Y happens") 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/DebugLog"
      }
   ]
};

It is normally required for the alfresco/logging/DebugLog widget to be included on the test page, in order to test publications/subscriptions are occurring correctly.

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 further 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/DebugLog widget.

CustomCommand.js

Aikau uses a custom Leadfoot Command module (found at alfresco/CustomCommand), in order to provide extra methods on top of the default Leadfoot ones. It would be well worth while reading through that file to see the available ones.