HxTest Testing Framework
Hexane uses a custom testing framework for testing the backend code. Here is a quick overview on its capabilities, and how to use it.
Benefits
-
does not require registration of test cases
-
test cases can be manually or automatically named
-
Supports aborting the remaining tests if
-
any test fails
-
specific test(s) fail
-
-
no external pre-processing is needed
-
implicit support for fixtures
-
aborting tests still allows cleanup/takedown code to run
-
the only external dependancy is the STL
Available Macros
| Macro | Description |
|---|---|
| TESTCASE | Creates and registers a new, automatically named testcase. |
| HxT_TEST(name) | Creates and registers a new, manually named testcase. |
| HxT_FAIL(msg) | Fails a test unconditionally. |
| HxT_ASSERT(expr) | Asserts that expr is true. |
| HxT_ASSERT_EQUALS(v1, v2) | Asserts that v1 == v2. |
| HxT_ASSERT_DIFFERS(v1, v2) | Asserts that v1 != v2 |
| HxT_ASSERT_DELTA(v1, v2, tol) | Asserts that abs(v1 - v2) < tol |
| HxT_ASSERT_LT(v1, v2) | Asserts that v1 < v2 |
| HxT_ASSERT_LTE(v1, v2) | Asserts that v1 <= v2 |
| HxT_ASSERT_GT(v1, v2) | Asserts that v1 > v2 |
| HxT_ASSERT_GTE(v1, v2) | Asserts that v1 >= v2 |
| HxT_RUN_TESTS() | Runs all test cases. |
| HxT_ABORT_ON_FAIL() | Configures HxTest to abort execution on fail |
| HxT_NO_ABORT_ON_FAIL() | Configures HxTest to continue execution on fail |
Examples
#include "hxtest.h"
TESTCASE {
HxT_ASSERT( 1 + 1 > 1 );
HxT_ASSERT_EQUALS( 1 + 1, 2 );
}
TESTCASE {
HxT_ASSERT_EQUALS( 2 * 2, 5 );
}
int main() {
HxT_RUN_TESTS();
return 0;
}
produces the following output:
$ ./a.out Running 2 tests. simple.cpp:20: Expected (2 * 2 == 5), found (4 != 5) ****** Summary ****** Failed 1 of 2 tests. Success Rate: 50%.
Although, HxTest also allows for manual naming of test cases, ie, we could have written Example 1 as:
#include "hxtest.h"
HxT_TEST(testAddition) {
HxT_ASSERT( 1 + 1 > 1 );
HxT_ASSERT_EQUALS( 1 + 1, 2 );
}
HxT_TEST(testMultiplication) {
HxT_ASSERT_EQUALS( 2 * 2, 5 );
}
int main() {
HxT_RUN_TESTS();
return 0;
}
Aborting Tests if an Assert fails
HxTest can abort the execution of the test driver if an assert fails. The program does not simply exit - the execution continues after the HxT_RUN_TESTS() call. That way, if any clean up, or teardown is needed, such will not be skipped when an assert fails.
#include "hxtest.h"
TESTCASE {
HxT_ASSERT_DIFFERS(5, 4);
}
int main() {
// abort execution if *ANY* assert fails
HxT_ABORT_ON_FAIL();
HxT_RUN_TESTS();
// execution continues here if an assert fails when
// when HxT_ABORT_ON_FAIL() is used.
return 0;
}
It is also possible to abort the execution if a specific assert fails. Such is accomplished by wrapping the assert in HxT_ABORT_ON_FAIL() and HxT_NO_ABORT_ON_FAIL() calls.
#include "hxtest.h"
TESTCASE {
// abort execution if this, single assert fails
HxT_ABORT_ON_FAIL();
HxT_ASSERT_DIFFERS(5, 4);
HxT_NO_ABORT_ON_FAIL();
// even if this assert fails, the program will continue
HxT_ASSERT_EQUALS(5, 4);
HxT_ASSERT_EQUALS(4, 4);
}
int main() {
HxT_RUN_TESTS();
return 0;
}
Fixtures
Although HxTest has no explicit support for fixtures, we can achieve the same effect by using a class. The following example illustrates this.
#include "hxtest.h"
// implicit fixture
class aFixture {
public:
int x;
int y;
// setup
aFixture() {
x = 5;
y = 3;
}
// teardown
~aFixture() {
}
} fix;
TESTCASE {
HxT_ASSERT_EQUALS(fix.x, 5);
}
TESTCASE {
HxT_ASSERT_EQUALS(fix.y, 3);
}
TESTCASE {
HxT_ASSERT_LT(fix.x, fix.y);
}
int main() {
HxT_RUN_TESTS();
return 0;
}
Misc
Hxtest also has the capability to allow ASSERT statements appear in functions.
#include "hxtest.h"
void validate(int a) {
HxT_ASSERT_GT(a, 3 + 5);
}
TESTCASE {
validate(14);
validate(1);
}
int main() {
HxT_RUN_TESTS();
return 0;
}
