briteTest is a lightweight, easy-to-use C/C++ framework for running unit and command-line tests focused on clarity and reliability. It provides a simple macro-based Runner API with customization macros and functions, a function-based Test API, fault-tolerant execution, clear reporting, comprehensive documentation, and no external dependencies.
License
SPDX-License-Identifier: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Preface
This document is intended for user and contributors who need guidance on using
briteTest including concepts and a quick start example. This also serves as the
<repo>/README.md for briteTest.
briteTest provides a Runner API and a Test API, each implemented with a single
.h / .c pair with no external dependencies and requiring only a POSIX.1-2001
environment and a C99-compliant compiler.
For a list of other documents and the repository layout, see the Documentation Guide.
For a glossary of terms, see the Glossary Reference.
A printer-friendly PDF file for this document is available.
Table of Contents
-
Introduction
1.1. Key Strengths
1.2. Quick Start
1.3. Requirements
1.4. Installation -
Contributing
2.1. For Public Users
2.2. For Contributors -
Runner Framework and API
3.1. What the Runner Framework and API Does
1. Introduction
1.1. Key Strengths
- Lightweight design - minimal files, minimal API surface, easy to embed.
- Macro-based Runner API - simple orchestration with predictable control flow.
- Function-based Test API - tests are just C functions, easy to organize and debug.
- Fault-tolerant execution - protects the test suite from crashes and undefined behavior.
- Parallel and concurrent test execution,
- Clear reporting - readable summaries of passes, failures, and faults.
- Pure C implementation.
- Minimal footprint (single header + source cor the ).
- Optional process-isolated execution.
1.2. Quick Start
A test executable consists of your tests as C/C++ expressions/functions, and the orchestrator and test group functions you write using the Runner API that manages the execution.
- Copy 'runnerapi.h' and 'runnerapi.c' to your current directory:
cp /path/to/runnerapi.h .
cp /path/to/runnerapi.c .-
Create a file named
test_quick.cin the same directory. -
Copy and paste the code into
test_quick.c:
💻 Copy
#include "runnerapi.h"
// A simple test group function.
static RA_DECLARE_GROUP(test_quick)
{
RA_INIT_GROUP(test_quick, 1);
int a = 2;
int b = 2;
// 4 test assertions.
RA_TEST(a == b, , 0); // Pass
RA_TEST(a + b == 4, , 0); // Pass
RA_TEST(a - b == 1, , 0); // Fail
RA_TEST(RA_FAULT(1), , 0); // Fault
RA_RETURN;
}
// A simple orchestrator (main) function.
RA_DECLARE_ORCHESTRATOR(main)
{
RA_INIT_ORCHESTRATOR(main, quick, 1);
RA_PARSE_ARGS(2, "quick_test_report.txt");
RA_OPEN_REPORT("Test Quick Report");
// Single test category.
RA_WRITE_RESULT(RA_GROUP(test_quick), "Quick tests");
RA_CLOSE_REPORT("Note: This report is a very simple examplexx.\n"
"Note: Multiple test categories can be added using multiple\n"
" test functions.\n"
"Note: Orchestrator (`main`) and test functions can be placed in\n"
" individual modules (.c files).\n"
"Note: Parameters can be set to run tests in parallel, isolate\n"
" a test to a separate thread or process, etc.\n"
"Note: The expression for RA_TEST can reference functions to\n"
" provide a more complex test. A non-zero result indicates\n"
" pass and a zero result indicates fail. If a fault occurs\n"
" executing the expression, it is detected and counted in\n"
" the report as a fault.\n"
"Note: Larger projects can place files in a more conventional\n"
" layout (e.g., `include/` and `src/`, but this example keeps\n"
" everything in your current directory for simplification.\n"
"Note: See root README.md for for additional API features.\n");
RA_EXIT;
}- Build the executable
test_quickin your current directory:
cc -std=c99 -Wall -Wextra -o test_quick test_quick.c runnerapi.c- Run it:
./test_quick- View
quick_test_report.txtin your current directory:
less quick_test_report.txt # Press 'q' to quit💻Example of the Report
Example of the report:Test Report
Pass Fail Fault
--------------------------------------------------
1. Orchestrator 4
2. Guard 1 and 2 6
--------------------------------------------------
Total 10
2. Contributing
briteTest welcomes feedback and contributions from the community. This section explains how to engage with the project based on your interest level.
2.1. For Public Users
If you use briteTest and want to provide feedback, ask questions, or suggest features:
- Ask questions about using briteTest
- Suggest features and improvements
- Report bugs and share workarounds
- Share examples and best practices
GitHub Discussions is the public engagement channel. All feedback is welcome and will be reviewed by the maintainers.
Follow releases:
Subscribe to releases to get notified about new versions and improvements.
2.2. For Contributors
To contribute code or documentation:
-
Request contributor access via GitHub Discussions or contact the maintainers
-
Review the Contributor Guide for detailed requirements on:
- Branching model and workflow
- Coding standards
- Documentation guidelines
- Testing requirements
- Pull request process
-
Add to contributors list - Once approved, you'll be added to
config/contributors.mdwith one of these roles:- C (Contributor): Can create branches and submit changes
- R (Reviewer): Can also review pull requests
- A (Approver): Can merge changes and manage releases
Pull requests are internal to contributors - The development workflow is visible only to contributors. Use GitHub Discussions for public feedback on features or issues.
3. Runner Framework and API
The Runner Framework (implemented using the Runner API) executes all test expressions (that implement the tests), aggregates results, and produces the report. This is the framework used by your test executable.
The Runner API provides typedefs, enums, macros, and functions for writing tests. Developers use this API to express expected behavior, group related tests, and define optional setup/teardown logic.
3.1. What the Runner Framework and API Does
The Runner framework coordinates test execution from the orchestrator down to individual test groups. It initializes the run, applies include and concurrency settings, executes the requested groups, captures pass/fail/fault results, and writes the final report.
The Runner API provides the macros and helper types used to define the orchestrator, declare test groups, control execution flow, and handle fault detection and reporting.
4. Running Tests
How to invoke the runner from main(), including optional parameters such as
output paths or configuration flags.
5. Report Generation
How the Runner Framework/API collects pass/fail information and formats it for output.
6. Customization
Notes that you can build your own runner logic if you need custom ordering, filtering, or integration behavior.
7. Test Report
Describes the structure of the test report, failures, optional details, and how to consume it in tooling or CI.
8. Advanced Features and Topics
Filtering tests and custom report writers are available in the User Guide.
9. Test Expressions
How to write a test expression for RA_TEST(expr) and how expressions are
evaluated.
10. Setup and Teardown
Optional per-group or per-test initialization and cleanup helpers.
11. Test Groups
How to organize related tests into groups for readability and logical structure.
12. Concurrent Tests
How to mark tests as concurrent and how Runner Framework handles parallel execution safely.
13. Isolation
Isolation controls how much separation is used when running tests.
- Same-thread execution is the default and has the lowest overhead.
- Thread-isolated execution keeps tests separated without switching to a separate process.
- Process-isolated execution provides the strongest containment for faults, crashes, aborts, and other disruptive failures.
Use the lightest mode that still gives you the safety you need for the code under test.
14. Test API
The Test API provides macros and functions for writing tests. Developers use this API to express expected behavior, group related tests, and define optional setup/teardown logic.
The Test API also includes execution/runtime, filesystem/path, environment, process-result, string/text, extended file operation, JSON data extraction, and resource management helpers.
See the Test Reference for a complete list of helpers provided by the API.
The following two sections provide examples of file and compare functions.
14.1. File Functions Examples
These helpers cover file and directory-related functions in the Test API.
Examples include:
- Filesystem predicates:
ta_exists - File and directory operations:
ta_copy_file - Temporary and cleanup helpers:
ta_make_temp_dir
14.2. Compare Functions
These helpers cover comparison and matching functions in the Test API.
Examples include:
- Path, file, and directory comparisons:
ta_compare_dirs - Metadata and binary comparisons:
ta_compare_path_metadata - JSON helpers:
ta_compare_json - Text and pattern helpers:
ta_compare_text_normalized
