Workspace 6.21.5
Writing a Unit Test

Introduction

Testing is an important component of software development. When you add a new functionality such as an operation to the plugin, you may want to create a unit test to keep a record of some relevant use cases: what output value is expected when given some specific input values. The unit tests also make it easier for any person who wants to check - at a later time - if any new changes to the code has broken the original use cases, without having to read through the code of the operation to figure them out. This is called a regression test and aims at detecting any backward incompatibilities introduced by the new changes.

Contents


Sample files used in this tutorial


Using the "Create Workspace Test" wizard

Assuming we want to write a unit test for the CalculateRectangleArea operation, we can use the Create Test wizard to generate the test source code, include the correct file headers and update the CMakeLists.txt to add our test. To start the wizard:

  1. Navigate to the Development menu and select Create workspace test
    Using the "Create workspace test" code wizard
  2. A window will be displayed that looks similar to this:
    The Create Workspace Test wizard

Let's start by filling in the fields on the form:

  • Test directory: The directory in which our test source files will be created. Point this to {PluginDir}/Tests where {PluginDir} is the location of your plugin source.
  • Test class name: The C++ class name for our unit test. We will call ours TestCalculateRectangleArea as we are writing a unit test for the Multiplier operation.
  • Namespace: The namespace used for the class. We will use CSIRO::Testing as many existing tests in Workspace.
  • Operation type: The operation type that is the subject of this unit test. We will select operation CalculateRectangleArea in the menu.
  • Brief description: This will appear in the code as a short comment describing what the test does. We will enter the text "A unit test for operation CalculateRectangleArea".
  • GUI-less: Check this box if the unit test does not need any graphical user interface, as in our case here we leave it checked.
Note
At any time you can check the purpose of these fields by hovering over them with the mouse and reading the tooltips (as shown above).

Our form will now look similar to this:

Our values entered into the wizard
  1. Click the Next button

You will now see a screen showing a list of plugins that can be linked to your test.

Selecting library dependencies

If your unit test depends on code in any of the listed plugins, you will need to select it here. In this tutorial:

  1. Select the Simple library, since the operation CalculateRectangleArea is part of that library.
  2. click Next

The next screen shows copyright notices that you can include in each of the source files in your plugin.

Select none for this tutorial
  1. Click Generate

Workspace will now generate the code for our new test and place it in the directory that we selected earlier ({PluginDir}/Tests). If you navigate to this directory, you'll see that it has created or updated the following files:

Customising the auto-generated code

In this section, we're going to customise our unit test. To do this, we need to modify the new file test_calculaterectanglearea.cpp

Let us take a look at the included header files section, we can see that calculaterectanglearea.h is already included by the Wizard. Since we also use the Rectangle data type in the test, we must include its header here manually:

#include "calculaterectanglearea.h"
#include "qglobal.h" // This is where QT_VERSION is defined
#include "rectangle.h"

The wizard automatically generates two test functions for us: initTestCase() and testRunnerscenario1(). We are going to leave initTestCase() as it is, and modify testRunnerscenario1() so that it does something useful.

In our test function testRunnerscenario1, we begin by creating an operation CalculateRectangleArea.

// Instantiate the operation to be tested
OperationRunner runner(OperationFactoryTraits<CalculateRectangleArea>::getInstance());
CalculateRectangleArea* operation = static_cast<CalculateRectangleArea*>(runner.getOperation());
const DataExecution::Operation * operation
Definition: connectworkspacetotopleveloperationactions.cpp:60

We can then populate the operation inputs with our test values by adding the following lines of code

Rectangle& rectangle = operation->getInputValue<Rectangle>(QString("Rectangle"));
rectangle.setWidth(4);
rectangle.setHeight(13);

and execute the operation with

QVERIFY2(runner.runOnceAndWait(), "Failed to run");

Finally, we check that the operation produces the expected output by adding the following lines of code

double area = operation->getOutputValue<double>(QString("Area"));
QVERIFY2(area == 52, "The calculation done be the operation is wrong.");

Building

Ensure that you have enabled the BUILD_TESTING checkbox in your makefile as this line will tell the build tool to also build all tests when it builds our plugin.

Check the BUILD_TESTING box in your make file

Now we can initiate the build command, for example in Linux: navigate to the plugin build directory and run make.


Running tests

Once built, you should see subdirectory Tests in the plugin build directory. Inside Tests there is an executable file called test_calculaterectanglearea. This is our unit test ready to be executed. You cannot run this file directly, as the environment will not be set up properly, but through workspace-batch.exe. The most convenient way do this is to add both the Workspace bin and your test bin directories to your path first. See Running the workflow from the command line . Otherwise, navigate to your application bin directory. Depending on your installation directory, under Windows you might run:

"C:\Program Files\csiro.au\workspace\bin\workspace-batch.exe" –launch test_calculaterectanglearea.exe

The execution of the test should produce this output

********* Start testing of CSIRO::Testing::TestCalculateRectangleArea *********
Config: Using QtTest library 5.12.5, Qt 5.12.5 (x86_64-little_endian-lp64 shared (dynamic) release build; by MSVC 2017)
Adding Built-in version 6.0.0
PASS   : CSIRO::Testing::TestCalculateRectangleArea::initTestCase()
PASS   : CSIRO::Testing::TestCalculateRectangleArea::testRunnerScenario1()
PASS   : CSIRO::Testing::TestCalculateRectangleArea::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of CSIRO::Testing::TestCalculateRectangleArea *********

which means all methods of the test class have run successfully, in particular testRunnerScenario1.


Summary

This tutorial has presented the Create Test wizard and the test code, how to write a test, compile and run it.


Next steps

The following tutorials are suggested as next steps: