Version 4 (modified by robert, 6 years ago)

--

Enabling the framework

jala.Test can be enabled by simply adding the directory as an additional repository to the application that should be tested. Add the following line to the section of the application in apps.properties:

[name].repository.[nr] = modules/jala/util/Test/code

Replace [name] with the name of your application and [nr] with the ordinal number of the repository. You can safely add jala.Test as last repository, there's no need to follow a specific repository order.

With this your application will have an additional root action called "runner". Point your browser to the URL of your application and append "runner" to it, eg. http://localhost:8080/myapp/runner.

Creating test files

Tests for jala.Test are organized in separate files, each one containing at least one function that will be run by the test runner. By concept the test files are not part of the application, but should be placed somewhere outside the application code. This prevents the application from being cluttered with test files. A good way to organize the application structure is to put the application code in a subdirectory called code and the test files in a directory tests on the same level:

myApp/code -> the application code
myApp/tests -> the tests for this application
myApp/docs -> the application documentation
...

A test file must be a JavaScript file with the extension .js, and preferably a file name containing the realm of the test. Besides the extension there are no restrictions for the file name.

The structure of a test file

A test file basically consists of a number of test functions, which must all be defined as global functions, plus an Array called "tests" containing the test functions to be executed by the runner. This way you can define the order of execution. So a simple test function might look like this:

/**
 * Declare which test methods should be run in which order
 * @type Array
 * @final
 */
var tests = [
   "testOne",
   "testTwo",
];

var testOne = function() {
   [test code ...]
   return;
};

var testTwo = function() {
   [test code ...]
   return;
};

There are no restrictions whatsoever regarding the names of the test functions, prefixing them with "test" is just a convention which you might follow or not. Please mind that the test runner will only execute those functions specified in the "tests" Array, all others will be ignored. Of course you can call additional methods defined in a test file from inside a test function, if it helps structuring a test.

In addition, the test runner looks for a special setup method which, if defined in a test file, will be excecuted before any test function. Use this to fulfill special requirements for the tests to pass. In this case you might also want to define a function called cleanup which will be executed by the test runner after executing the test. cleanup will be executed regardless of whether the test passed or failed, to ensure that even in case of a failure the test leaves nothing behind.

jala.Test contains a skeleton.js file in the distribution which you can use as a template for creating test files. For more examples on how test files can be structured have a look at the test files included with jala in the directory tests.

Altough the test files are stored outside the application, they are executed within the application, so from within a test function you can access basically everything provided by the application.

For testing values jala.Test provides a set of assertion functions. All of them have one feature in common: you can add an optional comment string at the beginning of the arguments, which will be displayed in the detail view of a test in the runner, eg.:

function testRoot() {
   var size = root.size();
   assertEqual("Testing the number of children of root", size, 2);
}

Besides the optional comment at the beginning all assertion functions require exactly the arguments specified in the API documentation of jala.Test.

An important note about using app.addRepository() inside a test file: don't do it. Due to the way jala.Test evaluates a test file, this will lead to unpredictable results, possibly breaking both the test and affecting the application in a negative way. Instead, include the repository in the application code.

Running tests

As explained before, by adding jala.Test as repository to the application that you want to run tests agains the application will get a new root action called "runner". To execute the tests the runner needs to know where to find them, namely the directory that contains the test files.

By default, the test runner expects the files to be located in a directory called tests on the same level as the directory containing the application code. So if you followed the application structure described above, the runner should instantly find and display the test files.

In any other case, you'll need to tell the runner where the tests directory is located. This can be done by adding a property tests to the app.properties file of the application that should be tested.

Either way the test runner will display a list of test files on the left. Clicking on one of the file names will run the test. If you want to run several tests at once, simply select them by clicking on the checkbox and when finished on the "Execute" button.

Screenshot of test runner

On the right the runner displays both a summary of the test run, including the number of test functions executed and how many of them passed resp. failed. Below you'll find detailed information about the test, listing every test method executed, it's execution time and status.

Screenshot of test runner

When a test function fails, the runner will immediately stop the execution of the test, ignoring any following methods. However it will execute the cleanup method if defined in the test file to ensure that the test doesn't leave any leftovers behind. The detail information about the failed test method will include a message telling about the reason why the test failed, and a stack trace that helps finding the line in the test file that failed, possibly including any methods called therein.

Screenshot of test runner

Using the Http client

jala.Test includes a simple HTTP client based on the Helma Http library that allows you to issue HTTP requests from within a test. However, this client stores any cookies received from the application being tested, which allows to eg. log a test user in and perform various actions, this way simulating a user's "walk" through an application. The client can be simply accessed from within every test function:

/**
 * Log in using a test account
 */
function testLogin() {
   var url = root.href("login");
   var result = httpClient.submitForm(url, {
      username: "jala",
      password: "secret"
   });
   assertEqual(result.code, 200);
   assertStringContains(result.content, "Welcome to Jala");
}

The above sample code will log a user "jala" in at the application being tested. The result object received contains among other properties the HTTP result code, and the resulting HTML page. Using standard assertion functions you can test if the result is what should be returned in case of a success (in the above example using the assertStringContains method).

Attachments