Unit testing

Unit testing a dizmo

How do we write unit tests for client-side code that does not have actual units?

Let us consider a unit. Ideally, it is a pure function that you can deal with in particular way — a function that always returns the same result for a specific input. In this case, unit testing is straightforward. As we do not always have the ideal case, we have to deal with the side effects, which we do with DOM manipulation.

However, we still recommend to structure the code into units and then build the unit tests accordingly.

Build and run tests

To build tests, run the command python manage.py test manage.py test. With the command python manage.py test:zip you can create a .dzm file for each test, and with test:deploy you can build and instantly deploy your test to the deployment_path as specified in the configuration file.

$ python manage.py test:zip

You will see the following terminal output:

Successfully built the test: ExampleTest.
Successfully zipped the test: ExampleTest.

The built tests are located in the build directory:

MyProject5_ExampleTest          MyProject5_ExampleTest_v0.1.dzm

Install (drag and drop) the built tests (.dzm files) into dizmoViewer to run the tests and display the test results.

Add your own tests

In your Grace project root directory, change to the test/javascript folder:

$ cd test/javascript

When you ran the command grace new Grace generated the file test_dizmo.js in the folder test/javascript. You can add your tests to this file:

module('dizmo tests');
test('test case one', function(assert) {
    // do testing here.
});

replace // do testing here. with your own test code (test case one and test case two.:

test('test case one', function(assert) {
    var height = 150;
    var dizHeight;

    expect(1);

    dizmo.setAttribute('geometry/height', height);
    dizHeight = dizmo.getHeight();

    assert.strictEqual(dizHeight, height, 'dizmo height is 150');
});

test('test case two', function(assert) {
    var sm;

    expect(1);

    sm = viewer.getAttribute('system/systemMemory');
    assert.isNumber(sm, 'systemMemory is a number');
});

Again, run python manage.py test:zip to recreate the tests and drop the updated .dzm file into dizmoViewer.

It is recommended to split up the file test_dizmo.js into different modules and files as your project grows.

First, create a new file in the same directory as dizmo_test.js, for example let's call it dizmo_positioning.js

module('positioning tests');

test('geometry/x', function(assert) {
    var val;

    viewer.setAttribute('geometry/x', 100);
    val = viewer.getAttribute('geometry/x');

    assert.strictEqual(val, 100, 'geometry/x is set to 100');
});

The file dizmo_positioning.js contains the new module name and a third test. This new file containing the new module needs to be included into the test itself.

Edit the file test_ExampleTest.js in the 'test/tests' folder and add //= require test_mystuff:

//= require CustomAssertions
//= require test_dizmo
//= require test_mystuff

Finally run python manage.py test:zip to recreate the tests and drop the updated .dzm file into dizmoViewer.

You now have three tests in two modules.

Practical example

We will add a test to verify the height. We change into the directory 'test/javascript' to edit the file test_dizmo.js.

$ cd test/javascript/

We add the test case one

test('test case one', function(assert) {
    var height = 170;
    var h;

    expect(1);

    dizmo.setAttribute('geometry/height', height);
    h = dizmo.getHeight();

    assert.strictEqual(h, height, 'dizmo height is 170');
});

Then with python manage.py test:zip we create the testfile 'Gauge_ExampleTest_v0.1.dzm' which we drop into dizmoViewer. If all goes well, we should see our test passing.

Gauge unittest
Gauge unittest

External resources