Overview and Core Principles
The Greatest framework is designed as a single-header C testing library that emphasizes minimalism and efficiency. Its architecture targets resource-constrained environments such as embedded systems where memory overhead is a critical concern. By avoiding external dependencies and complex build configurations, the framework ensures high portability across different compilers and platforms. The API is structured to reduce boilerplate, adhering to the principle that testing logic should remain transparent and straightforward.
Testing Workflow
Integration begins by including the framework header in the source files. Test cases are defined using the TEST macro, encapsulating specific verification logic. Execution is handled via RUN_TEST for individual cases or RUN_SUITE for grouped collections. The framework provides a variety of assertion macros—such as ASSERT_EQ for equality checks and ASSERT_TRUE for boolean validation—to automate the verification of expected outcomes against actual results.
Basic Implementation Example
The following example demonstrates a simple test case verifying a basic arithmetic operation. The PASS() macro is required to indicate successful completion of the test body.
#include "greatest.h"
TEST arithmetic_check(void) {
int x = 10;
int y = 25;
int total = x + y;
ASSERT_EQ(total, 35);
PASS();
}
int main(int argc, char **argv) {
GREATEST_MAIN_BEGIN();
RUN_TEST(arithmetic_check);
GREATEST_MAIN_END();
}
Modular Test Organization
For larger projects, tests should be organized into suites based on functional modules. This involves declaring external suites in the main runner and defining them in separate source files.
Main Test Runner
#include "greatest/greatest.h"
/* External Suite Declarations */
SUITE_EXTERN(suite_io);
SUITE_EXTERN(suite_parser);
GREATEST_MAIN_DEFS();
int main(int argc, char **argv) {
GREATEST_MAIN_BEGIN();
/* Execute functional suites */
RUN_SUITE(suite_io);
RUN_SUITE(suite_parser);
GREATEST_MAIN_END();
}
Module Implementation
#include "greatest/greatest.h"
#include "my_system_api.h"
#define TEMP_DATA_PATH "./cache/temp.dat"
TEST create_file_check(void) {
int status = fs_create(TEMP_DATA_PATH);
ASSERT_EQ(status, 0);
PASS();
}
TEST delete_file_check(void) {
int status = fs_remove(TEMP_DATA_PATH);
ASSERT_EQ(status, 0);
PASS();
}
SUITE(suite_io) {
RUN_TEST(create_file_check);
RUN_TEST(delete_file_check);
}