"TEST_SUITE_" prefixes all library constants, and "testSuite" prefixes all library functions (without quotes). The exceptions are TEST_PASS and TEST_FAIL, since they deal with assertions. All assertions start with "assert".
Constants are snake case (underscores separate words) with all uppercase letters.
Function names are camel case with the first letter being lowercase.
Feel free open the example files (packaged with the download in v2.0.0) and follow along if you don't want to write out the following code. For a more complex, practical example, checkout the default branch of the AMX Volume Control library.
The first step is to set up an AMX NetLinx project that will house your test code. This test project should include the functions from your production project and the test suite include file. This project will end up being compiled and run on a NetLinx master.
Add amx-test-suite.axi to the project's include files, as well as the include file(s) containing your project's functions. DO NOT include files that will run code in the mainline. In the file that will contain your tests, add an include to amx-test-suite just below PROGRAM_NAME.
At this point the program will fail to compile, which is normal. The reason is because the test suite is looking for the testSuiteRun() function, which is where your project's tests are defined. Let's go ahead and add that to the DEFINE_MUTUALLY_EXCLUSIVE section.
~~~~~
:::c
(***********************************************************)
(* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)
define_function testSuiteRun()
{
// Tests go here.
}
~~~~~
For the sake of the demonstration, let's create a couple of simple functions that we can test. In the file containing mock production code (the "my-project-functions" include file in the picture above), create two functions: add() and subtract(). Let's add an intentional error in the subtract() function to see how it's caught.
~~~~~
:::c
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)
define_function sinteger add(sinteger x, sinteger y)
{
return x + y;
}
define_function sinteger subtract(sinteger x, sinteger y)
{
// Intentional error for test harness to catch.
return x + y;
}
~~~~~
All of the user-defined tests are performed with assertions. The most basic assertion, assert(x, name[]), accepts parameter x which is expected to evaluate to true, and a name or description of the assertion, name[]. If the expression evaluates to false, the test will fail. The function list contains a complete list of assertions, as does the amx-test-suite.axi file. Let's create some assertions to test the add() and subtract() functions.
~~~~~
:::c
define_function testSuiteRun()
{
// Test add() function.
assert(add(1, 2) == 3, '1 + 2 = 3');
// Test subtract() function.
assert(subtract(5, 4) == 1, '5 - 4 = 1');
}
~~~~~
Compile the testing workspace and load it onto the master. Launch the AMX NetLinx Diagnostics Program and connect to the master when it's ready. Click the "Enable Internal System Diagnostics" button, and then navigate to the "Control Device" tab.
The test harness communicates by sending strings to a virtual device. Under "Device To Control", set the device to 36000, port to 1, and system to 0. In the message box, type "run -v" (no quotes). Set the message type to string, and send the string to the device. The tests will proceed to run, notifying you of any failures.
As expected, the subtract() function didn't return the correct value. If you modify the source code to correct the error and run the tests again, you'll see all the tests pass.