Unit Testing API

API Reference


Unit testing is an important aspect of a quantifiable quality assurance methodology. Although unit testing requires some extra overhead (the writing of the unit tests) during the development process it can provide enormous benefits during the project life cycle.

One benefit of writing unit tests is that it gets the developer using the interface to the unit they designed. This forces the developer to think about, and hopefully design for, usability of the interface early in the development cycle.

Another major benefit to unit testing is that it provides a documented and verifiable level of correctness for the designed unit. This allows the developer to refactor the code more aggressively and to quickly verify its correctness. Unit tests can also be used to perform regression testing when adding new features.

Despite the benefits of unit testing, unit tests are often omitted because of the initial overhead of writing the tests and the complexity of testing frameworks. Legato's Unit Test Framework is simple to use and very flexible and lightweight consisting of some handy macros.

The Legato test framework outputs test results to the log in TAP format (prefixed by "TAP |") This allows test results to be processed with many test harnasses.

Setting Up the Test Framework

To setup the Legato Test Framework, call the LE_TEST_PLAN macro, once before any tests are started. The macro takes the total number of planned tests as single argument.

Performing Tests

To perform tests, call the LE_TEST_OK macro. The first argument is whether the test passed (true or false). The second argument is the name of the test.

For example:

#include "legato.h"
 
// Returns true if the test passes, otherwise returns false.
bool ComplexTest(void)
{
int expectedValue;
 
// Do some initializations and/or calculations.
...
 
// Call one of the unit-under-test's interface function and check it's return value against
// an expected value that was calculated earlier.
return (unitUnderTest_foo2() == expectedValue);
}
 
 
int main (void)
{
// Setup the Legato Test Framework.
 
// Run the tests.
// Do some initializations and/or calculations.
...
 
LE_TEST_OK(TestFunction(arguments) == EXPECTED_VALUE, "simple test");
LE_TEST_OK(ComplexTest(), "complex test");
 
// Exit with the number of failed tests as the exit code.
}

Exiting a Test Program

When a test program is finished executing tests and needs to exit, it should exit using the LE_TEST_EXIT macro.

If a test suite needs to exit early it should use the LE_TEST_FATAL() macro. This will log a message indicating the test suite has been aborted. LE_ASSERT() and LE_FATAL() macros should not be used as they will not print this message.

As a convenience you can also use the LE_TEST_ASSERT() macro which will abort the test suite if the test fails. This is useful if running further test cases is pointless after this failure.

Test Results

The LE_TEST_EXIT macro will cause the process to exit with the number of failed tests as the exit code.

Note
The log message format depends on the current log settings.

Multi-Threaded Tests

For unit tests that contain multiple threads run the various tests, these macros can still be used. However your test program should ensure that only one thread uses the unit test API at a time.