Writing Fixtures ๐
Fixtures provide a consistent and controlled environment for testing. Fixtures define a โsetupโ phase, where the necessary state is established, and a โteardownโ phase to clean up or reset the state. Fixtures help maintain reliability and repeatability in the testing process.
In Audition, there are three types of fixtures:
- Test fixtures are executed before and after each test case.
- Suite fixtures are executed before and after each suite.
- Runner fixtures are executed before and after the first and last test suite.
Audition registers fixtures implicitly, just as it does test cases, and invokes them at the appropriate times. The following subsections explore these fixtures and provide examples.
Test Fixtures ๐
Test fixtures are run before and after each test case. They are useful for initializing the context for each test and for allocating and releasing per-test resources.
In Audition, test fixtures are defined with TEST_SETUP and TEST_TEARDOWN. The former is invoked before each test case is executed, while the latter is invoked after each test case.
Test fixtures are unique to a suite, meaning you can only define one setup and teardown test fixture per suite. If you attempt to define duplicate test fixtures, Audition will terminate with a runtime error.
The following code example demonstrates how these fixtures can be used to open and close a new bank account before each test case, ensuring that each test case begins with an empty bank account:
static BankAccount *account;
TEST_SETUP(bank) {
account = account_open();
}
TEST_TEARDOWN(bank) {
account_close(account);
}
Suite Fixtures ๐
Suite fixtures are run before the first and after the last test case of a suite, respectively. They are useful for initializing resources shared by all tests in a test suite.
In Audition, suite fixtures are defined with SUITE_SETUP and SUITE_TEARDOWN. Code in the SUITE_SETUP fixture executes before any test in the suite, and code in the SUITE_TEARDOWN fixture executes after all tests of the suite have completed. Suite fixtures are unique to the suite, meaning you can only define one setup and teardown suite fixture per suite.
In the following example, a database connection is opened for the website
test suite. This connection, represented by the pointer db
, will be closed only after all tests in the suite have executed:
static DatabaseConnection *db;
SUITE_SETUP(website) {
db = database_open();
}
SUITE_TEARDOWN(website) {
database_close(db);
}
Runner Fixtures ๐
Test runner fixtures are invoked once when the test runner executable starts and again before it terminates. These fixtures typically prepare the global state necessary for all test suites.
In Audition, test runner fixtures are declared with RUNNER_SETUP and RUNNER_TEARDOWN. Code in the RUNNER_SETUP fixture executes before the first test suite begins executing, while code in the RUNNER_TEARDOWN fixture executes after all test suites have executed.
In the following example, the runner invokes functions to initialize and free global resources:
RUNNER_SETUP() {
init_global_state();
}
RUNNER_TEARDOWN() {
free_global_state();
}