Test Definition Macros¶
Include mu/tiny/test.hpp for all macros on this page.
Test Group and Lifecycle¶
TEST_GROUP(group)¶
TEST_GROUP declares a test group. Expands to a struct definition; add
setup() and
teardown() inside it.
TEST_GROUP(MyGroup)
{
MyObject* obj;
void setup() override { obj = new MyObject; }
void teardown() override { delete obj; }
};
All tests in the group share a fresh instance of the struct (constructed
before setup(), destroyed after
teardown()).
TEST(group, name)¶
TEST defines a test belonging to group. The { ... } block that
follows is the test body.
TEST(MyGroup, DoesTheThing)
{
CHECK(obj->do_thing());
}
Skipping and Expected Failures¶
SKIPPED_TEST(group, name)¶
SKIPPED_TEST marks a test as skipped. It is registered but skipped during
normal runs. Use -rs to run skipped tests anyway.
SKIPPED_TEST(MyGroup, NotImplementedYet)
{
// will not run unless -rs is passed
CHECK(false);
}
Skipped tests appear in the summary count as “skipped”.
XFAIL_TEST(group, name)¶
XFAIL_TEST declares a test that is expected to fail. The test runner
treats a failure as a pass and a pass as a failure. Useful for
documenting known bugs that cannot yet be fixed.
XFAIL_TEST(MyGroup, KnownBug)
{
CHECK_EQUAL(expected, buggy_function()); // currently produces wrong result
}
Metadata¶
TEST_PROPERTY(name, value)¶
TEST_PROPERTY attaches a key/value metadata pair to the currently running
test. Emitted in JUnit XML output as <property> elements. Useful for
CI tagging (e.g. requirement IDs).
TEST(MyGroup, Requirement42)
{
TEST_PROPERTY("requirement", "REQ-42");
CHECK(meets_requirement_42());
}
Ordered Tests¶
Normally mu::tiny runs tests in an unspecified order (registration order,
possibly shuffled with -s [seed]).
OrderedShell lets you assign a
numeric level to selected tests so they run in level order, independent of the
registration order of all other tests.
TEST_ORDERED(group, name, level)¶
TEST_ORDERED declares a test that runs at the given level. Lower
levels run first. Tests at the same level run in registration order relative to
each other (FirstEvent and SecondEvent both run at level 20 below).
// Demonstrates TEST_ORDERED: tests that run in level order across the suite.
//
// Use case: a stateful system (here, a simple in-memory event log) that must
// be initialized before use and flushed on shutdown. Ordered tests let each
// phase be a separate, named test rather than one monolithic test body.
#include "mu/tiny/test/Ordered.hpp"
#include "mu/tiny/test.hpp"
namespace {
struct EventLog
{
const char* entries[8]{};
int count{ 0 };
bool initialized{ false };
bool flushed{ false };
void init()
{
initialized = true;
count = 0;
}
void append(const char* msg)
{
if (count < 8) {
entries[count++] = msg;
}
}
void flush()
{
count = 0;
flushed = true;
}
};
EventLog g_log;
} // namespace
TEST_GROUP(OrderedDemo)
{};
// Regular test — unordered tests run before the ordered block.
TEST(OrderedDemo, StartsUninitialized)
{
CHECK(!g_log.initialized);
}
// Level 10: initialize.
TEST_ORDERED(OrderedDemo, Init, 10)
{
g_log.init();
CHECK(g_log.initialized);
CHECK_EQUAL(0, g_log.count);
}
// Level 20: record two events. Tests at the same level run in
// registration order (FirstEvent before SecondEvent).
TEST_ORDERED(OrderedDemo, FirstEvent, 20)
{
g_log.append("startup");
CHECK_EQUAL(1, g_log.count);
}
TEST_ORDERED(OrderedDemo, SecondEvent, 20)
{
g_log.append("ready");
CHECK_EQUAL(2, g_log.count);
}
// Level 30: verify accumulated state from both level-20 tests.
TEST_ORDERED(OrderedDemo, VerifyLog, 30)
{
CHECK_EQUAL(2, g_log.count);
STRCMP_EQUAL("startup", g_log.entries[0]);
STRCMP_EQUAL("ready", g_log.entries[1]);
}
// Level 40: shutdown.
TEST_ORDERED(OrderedDemo, Shutdown, 40)
{
g_log.flush();
CHECK_EQUAL(0, g_log.count);
CHECK(g_log.flushed);
}
The leading TEST(OrderedDemo, StartsUninitialized) is a regular test: it
runs before the ordered block. Ordered tests run as a block after all unordered
tests by default.
Listing Ordered Tests¶
Pass -lo to print each ordered test’s location as
group.name.file.line:
$ ./my_tests -lo
OrderedDemo.Init.examples/tests/OrderedTest.test.cpp.53
OrderedDemo.FirstEvent.examples/tests/OrderedTest.test.cpp.62
OrderedDemo.SecondEvent.examples/tests/OrderedTest.test.cpp.68
OrderedDemo.VerifyLog.examples/tests/OrderedTest.test.cpp.75
OrderedDemo.Shutdown.examples/tests/OrderedTest.test.cpp.83
When to Use Ordered Tests¶
Ordered tests are appropriate when:
You are integration-testing a stateful system (e.g. a database, a file system) where setup steps must precede query steps.
The test itself mutates persistent state that subsequent tests depend on.
Avoid them when:
Tests can be made independent through
setup()/teardown()— independent tests are more robust and can be run in isolation.You want the
-s [seed](shuffle) flag to help detect ordering dependencies — ordered tests are excluded from the shuffle.
C Wrapper Macros¶
These bridge C test files into the C++ test runner. See Testing C Code for full details.
Macro |
Purpose |
|---|---|
Declares a C++ |
|
Wires C setup into the C++ group’s |
|
Wires C teardown into the C++ group’s |
|
Wires a C test function into a C++ |
|
Same as above but skipped |
|
Same as above but expected to fail |
|
Wires a C test function into a |
Examples¶
File |
Demonstrates |
|---|---|
|
|
C-wrapper two-file pattern with |
|
|