Guided Tour¶
To visualize the functionality of the Igor Pro Universal Testing Framework, we will start with a guided tour in which we create our first unit and test it with the Igor Pro Universal Testing Framework. The tour will cover the following steps:
Please make sure that the framework has been properly installed if you wish to follow the guide. For the framework to work, the files from the procedures folder should be placed into the User Procedures Folder of your Igor Pro setup.
Creating a unit¶
We will start by creating a simple unit.
The following formula gives the diameter \(d\) of a carbon nanotube:
The natural numbers \(n\) and \(m\) define the carbon nanotube type. \(a_0\) is the unit cell lattice constant of graphene (Understanding the background of the above formula is not required here).
The formula is easily translated into Igor Pro code:
1#pragma TextEncoding = "UTF-8"
2#pragma rtGlobals=3
3
4// calculate carbon nanotube diameters
5Function diameter(n, m)
6 Variable n, m
7
8 return 0.144 / 3.1415 * (3 * (n^2 + n*m + m^2))^(0.5)
9End
Testing the unit¶
If we want to rely on this formula with other calculations, we have to test if the output of this function is both correct and within our required accuracy range. To perform these two tests, we define a Test Case.
1#pragma TextEncoding = "UTF-8"
2#pragma rtGlobals=3
3
4#include "igortest"
5
6Function testDiameter()
7 // the (6,5) type is 0.757nm in diameter
8 REQUIRE_CLOSE_VAR(diameter(6, 5), 0.757, tol=1e-3)
9 // this is the same value as for the (9,1) type.
10 REQUIRE_EQUAL_VAR(diameter(6, 5), diameter(9, 1))
11End
The test case testDiameter
contains two checks. Both are required to
pass the test suite. In the context of this framework we will refer to them as
assertions. The first assertion
REQUIRE_CLOSE_VAR
compares the two floating point numbers within the
given tolerance of 0.001nm. The second REQUIRE_EQUAL_VAR
uses a
mathematical peculiarity of the above formula to check if the calculation gives
correct output.
The test case function can be placed anywhere inside the main procedure file, but it can be considered good practice to separate test cases into a procedure file of their own. Such a separate procedure file that only contains test cases is called a Test Suite. A test suite can for example perform all the necessary tests for a unit.
Executing the test¶
To execute the test suite we use the RunTest()
directive. It accepts
the name of our test suite (the procedure window) as an argument. In our
example we have named the procedure window "test0"
.
•RunTest("test0")
Start of test "Unnamed"
Entering test suite "Unnamed"
Entering test case "testDiameter"
Leaving test case "testDiameter"
Finished with no errors
Leaving test suite "test0"
Test finished with no errors
End of test "Unnamed"
In the cosole output above, the highlighted line indicates that all tests within the current test suite have passed successfully. The unit is working properly. The full Igor Pro environment with our unit test should look like this:

Extending the test¶
Note, that we have defined a test case for the current capabilities of our
function diameter()
. The calculation is only exact up to the specified
error range. The high error is caused by a fixated value of
pi=3.1415
. To emphasize this, we can add an assertion to the test case
that will fail but will not affect the error counter. Such an assertion is done
with a WARN_* directive. Every REQUIRE_* assertion also has a
WARN_* variant, see:ref:AssertionTypes for a summary.
Function testDiameter()
// the (6,5) type is 0.757nm in diameter
REQUIRE_CLOSE_VAR(diameter(6, 5), 0.757, tol=1e-3)
// this is the same value as for the (9,1) type.
REQUIRE_EQUAL_VAR(diameter(6, 5), diameter(9, 1))
// warn if accuracy is not exact
WARN_CLOSE_VAR(diameter(6, 5), 0.7573453, tol=1e-7)
End
The output of RunTest()
will now include a warning assertion without
failing the test case:
•RunTest("test0")
Start of test "Unnamed"
Entering test suite "Unnamed"
Entering test case "testDiameter"
Entering test case "testDiameter"
0.757368 ~ 0.757345 with strong check and tol 1e-07: is false
Assertion "WARN_CLOSE_VAR(diameter(6, 5), 0.7573453, tol=1e-7)" failed in line 11, procedure "test0"
Leaving test case "testDiameter"
Finished with no errors
Leaving test suite "test0"
Test finished with no errors
End of test "Unnamed"
If the program should be extended to a higher level of accuracy, this warning
can be set to the corresponding REQUIRE
assertion. The program diameter
then has to be changed to reflect the
new requirement. In the current example, \(pi\) would need to be used
instead of only a handful of decimal places hardcoded.
In a test-driven workflow, the unit tests get extended before even changing anything at the code base. Defining the test case prior to any code production assures that the software development is not producing unnecessary (and untested) code.
A more elaborate example for defining a peak find functionality can be found in the examples section. For a quick start, also have a look at the first example.