A lightweight, single-header unit testing framework for C and C++ with zero dependencies
Features • Quick Start • Documentation • Examples • Contributing
- Overview
- Features
- Quick Start
- Examples
- HTML Reports
- Documentation
- Supported Platforms
- Building from Source
- Running Tests
- Contributing
- License
- Authors
- Acknowledgments
TST is a modern, lightweight unit testing framework designed specifically for C programs (with full C++ compatibility). Born from the frustration of dealing with complex test frameworks that require extensive build configurations and dependencies, TST provides a simple yet powerful testing solution in a single header file.
- 🚀 Zero Setup: Just include
tst.hand start writing tests - 📦 Single Header: Less than 300 lines of code, no external dependencies
- 🎯 Simple Syntax: Intuitive macros that feel natural in C
- ⚡ Fast: Minimal overhead, optimized for performance
- 🔍 Rich Output: Structured logs perfect for both humans and CI/CD pipelines
- 📊 HTML Reports: Beautiful interactive dashboards with source code extraction
- 🏷️ Tag-Based Filtering: Run specific test subsets with command-line tags
- 📈 Data-Driven Tests: Built-in support for parameterized testing
- ⏱️ Performance Timing: Integrated CPU time measurement
- 🔧 Flexible: Works with any C compiler on any platform
- ✅ Hierarchical Test Organization: Suites → Cases → Sections
- ✅ Multiple Assertion Types:
tstcheck,tstassert,tstexpect - ✅ Conditional Execution:
tstskipiffor runtime test skipping - ✅ Tag-Based Filtering: Selective test execution with
+Tag/-Tag - ✅ Data-Driven Testing: Automatic iteration over test data arrays
- ✅ Performance Measurement: Built-in
tstclockfor timing - ✅ Formatted Messages: Printf-style assertion messages
- ✅ Rich Diagnostics: Notes, output blocks, and custom logging
- 📊 Interactive Dashboards: Click to expand logs and source code
- 🎨 Syntax Highlighting: Color-coded C/C++ source with keyword highlighting
- 📁 Multi-Suite Support: Consolidate multiple test logs into one report
- 🌓 Light/Dark Themes: Toggle between themes for comfortable viewing
- 📈 Visual Statistics: Pie charts and progress bars for pass/fail/skip distribution
- 🔍 Source Extraction: Automatic extraction of test case source code
- 🎯 Line Number Mapping: Links between logs and source code
- 🛠️ No Build System Required: Direct compilation with any C compiler
- 📝 Self-Documenting: Test names serve as specifications
- 🐛 CI/CD Friendly:
--report-errorflag for build pipelines - 🌍 Cross-Platform: Linux, macOS, Windows (WSL, MinGW, MSVC)
- 🔗 Zero Dependencies: Uses only standard C library
Download tst.h and copy it to your project:
# Download from GitHub
curl -o tst.h https://raw.githubusercontent.com/rdentato/tst/main/src/tst.h
# Or clone the repository
git clone https://github.com/rdentato/tst.git
cp tst/src/tst.h /path/to/your/project/git clone https://github.com/rdentato/tst.git
cd tstCreate a file test_example.c:
#include "tst.h"
tstsuite("My First Test Suite") {
tstcase("Basic Arithmetic") {
tstcheck(1 + 1 == 2, "Addition works");
tstcheck(5 * 4 == 20, "Multiplication works");
}
tstcase("String Functions") {
tstcheck(strlen("hello") == 5);
tstcheck(strcmp("abc", "abc") == 0);
}
}# Compile (no special flags needed)
gcc -o test_example test_example.c
# Run tests
./test_exampleOutput:
----- SUIT / test_example.c "My First Test Suite" 2025-11-27 10:30:45
CASE,-- Basic Arithmetic
4 PASS| 1 + 1 == 2
5 PASS| 5 * 4 == 20
`--- 0 FAIL | 2 PASS | 0 SKIP
CASE,-- String Functions
9 PASS| strlen("hello") == 5
10 PASS| strcmp("abc", "abc") == 0
`--- 0 FAIL | 2 PASS | 0 SKIP
^^^^^ RSLT \ 0 FAIL | 4 PASS | 0 SKIP 2025-11-27 10:30:45
Test the same logic with multiple inputs:
tstcase("Factorial Tests") {
struct {int input; int expected;} tstdata[] = {
{0, 1},
{1, 1},
{5, 120},
{10, 3628800}
};
tstsection("Calculate factorial(%d)", tstcurdata.input) {
int result = factorial(tstcurdata.input);
tstcheck(result == tstcurdata.expected,
"Expected %d, got %d", tstcurdata.expected, result);
}
}Organize tests by type and run selectively:
tstsuite("API Tests") {
tstcase("Fast Unit Test", -SlowTests) {
tstcheck(quick_function() == 0);
}
tstcase("Database Integration", +RequiresDB, +Integration) {
tstcheck(db_connect() == 0);
tstcheck(db_query("SELECT 1") == 0);
}
}Run only fast tests:
./test_api -SlowTestsRun integration tests:
./test_api +IntegrationMeasure execution time with built-in timing:
tstclock("Sort 10000 elements") {
quicksort(array, 10000);
}
tstcheck(is_sorted(array, 10000));
tstcheck(tstelapsed() < 1000000, "Should complete in < 1s");Skip tests based on runtime conditions:
tstcase("Database Tests") {
int db_available = check_database();
tstskipif(!db_available) {
tstcheck(db_query("SELECT * FROM users") == 0);
tstcheck(db_insert("user1") == 0);
}
}For more examples, see the tutorial directory or the programmer's manual.
TST also provides tst.sh, a bash library for writing shell-based tests that produce TST-formatted output.
#!/bin/bash
source "path/to/tst.sh"
tstsuite_begin "Shell Script Tests" "$0"
tstcase_begin "File operations"
# Auto-detect line numbers
tstpass "test -f README.md"
result=$(cat README.md | wc -l)
if [ "$result" -gt 0 ]; then
tstpass "README.md has content"
else
tstfail "README.md has content" "File is empty"
fi
tstcase_end
tstcase_begin "Command tests"
tstnote "Testing basic commands"
# Explicit line number (for helper functions)
if ls /tmp > /dev/null 2>&1; then
tstpass $LINENO "ls /tmp succeeds"
fi
tstcase_end
tstsuite_end- TST-Compatible Output: Generates logs that work with
t2hHTML reports - Auto-Detect Line Numbers: Uses
${BASH_LINENO[0]}for automatic line tracking - Flexible API: Mirror of tst.h functions for bash scripts
- Helper Functions: Built-in comparisons (
tst_equal,tst_greater, etc.)
See the Programmer's Manual for complete tst.sh documentation.
The t2h utility converts test logs into beautiful, interactive HTML reports.
# From test output
./test_program | t2h > report.html
# From log files
t2h test1.log test2.log > consolidated.html
# With light theme
t2h --light test.log > report.html|
Interactive UI
|
Rich Visualizations
|
cd src
make t2h
# Or manually
gcc -o t2h t2h.c -lm| Document | Description |
|---|---|
| Programmer's Manual | Comprehensive guide with tutorials and examples |
| Reference Manual | Complete API reference for tst.h, tst.sh, and t2h |
| Tutorial | Step-by-step introduction to TST features |
| Design Documents | Architecture and implementation details |
- Test Suite: Top-level container (one per source file)
- Test Case: Group of related checks with partial results
- Test Section: Isolated subsection with setup/teardown
- Assertions:
tstcheck(continue),tstassert(abort),tstexpect(silent) - Tags: Runtime filters for selective test execution
- Data-Driven: Arrays named
tstdatafor parameterized tests
// Suite definition
tstsuite("Suite Name") { /* tests */ }
// Test organization
tstcase("Case Name") { /* checks */ }
tstsection("Section %d", val) { /* isolated checks */ }
// Assertions
tstcheck(expr, "message %d", val); // Continue on failure
tstassert(expr, "critical"); // Abort on failure
tstexpect(expr, "silent on pass"); // Only print failures
// Control flow
tstskipif(condition) { /* skipped tests */ }
// Tags (in tstcase)
tstcase("Test", +RequiresDB, -SlowTests) { }
// Diagnostics
tstnote("Info message %d", val);
tstprintf("Debug output\n");
tstouterr("Block output:") { tstprintf("...\n"); }
// Timing
tstclock("Operation") { /* code */ }
clock_t elapsed = tstelapsed();
// Data-driven
int tstdata[] = {1, 2, 3};
tstsection("Test %d", tstcurdata) { /* runs 3 times */ }TST has been tested and confirmed to work on the following platforms:
| Platform | Compiler | Status |
|---|---|---|
| Linux | gcc, g++, clang | ✅ Fully Supported |
| macOS | clang (Apple) | ✅ Fully Supported |
| Windows WSL2 | gcc, g++, clang | ✅ Fully Supported |
| Windows | MSVC (cl), MinGW | ✅ Fully Supported |
- C: C99 or later (C89 compatible with minor limitations)
- C++: C++98 or later (automatic
extern "C"handling)
- GCC 7.0+
- Clang 6.0+
- MSVC 2017+
- MinGW-w64 8.0+
# From repository root
make runtest
# Or manually
cd test
make
./tstruncd src
make t2h
# Or with specific compiler
CC=clang make t2h# From repository root
make# Run all tests
./test_program
# List available tests and tags
./test_program --list
# Return error code on failure (for CI)
./test_program --report-error# Enable specific tags
./test_program +RequiresDB +Integration
# Disable specific tags
./test_program -SlowTests
# Enable all tagged tests
./test_program +*
# Complex filtering (later overrides earlier)
./test_program +* -SlowTests +Integration# Set default options
export TSTOPTIONS="--report-error +* -ManualTests"
./test_program # Uses TSTOPTIONSWe welcome contributions! Whether it's bug reports, feature requests, documentation improvements, or code contributions.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
make runtest - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow the existing code style (K&R style, 2-space indents)
- Add tests for new features
- Update documentation as needed
- Keep commits focused and atomic
- Write clear commit messages
Found a bug? Have a question? Open an issue on GitHub.
- Discord: Join our community
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2023-2025 Remo Dentato
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...
Remo Dentato - Creator and Maintainer
- GitHub: @rdentato
See also the list of contributors who participated in this project.
- Inspired by the simplicity of testing frameworks like Catch2 and doctest
- Thanks to all contributors and users who provided feedback
- Special thanks to the C programming community
Current Version: 0.8.1-beta
Status: Active Development
Stability: Beta (API may change before 1.0 release)
- 1.0.0 Release with stable API
- JUnit XML output format
- Test coverage integration
- Visual Studio Code extension
- CMake integration helpers
⭐ If you find TST useful, please consider giving it a star on GitHub! ⭐
Report Bug • Request Feature • Documentation • Discord
Made with ❤️ by Remo Dentato
