Test Infrastructure
Zeal uses:- Qt Test Framework: Qt’s built-in testing framework
- CMake CTest: Test runner integration
- GitHub Actions: Continuous integration
Building with Tests
Enable Testing
Tests are enabled by default through theBUILD_TESTING CMake option:
CMake Configuration
The rootCMakeLists.txt includes:
BUILD_TESTING is ON.
Test Directory Structure
Tests are organized alongside the code they test:CMakeLists.txt: Test build configuration*_test.cpp: Test implementation files
Running Tests
Run All Tests
After building with tests enabled:Run Specific Tests
Run a specific test by name:Verbose Output
Show detailed test output:Run Tests Directly
You can also run test executables directly:Writing Tests
Test File Structure
Tests use the Qt Test framework. Here’s a typical test file structure:Key Components
- Test Class: Inherits from
QObjectwithQ_OBJECTmacro - Test Methods: Private slots that start with
test - Qt Test Macros:
QCOMPARE,QVERIFY, etc. - Test Main:
QTEST_MAIN(ClassName)macro - Moc Include:
#include "testfile.moc"
CMakeLists.txt for Tests
Each test directory needs aCMakeLists.txt:
Qt Test Assertions
Common Qt Test macros:QCOMPARE
Compare two values for equality:QVERIFY
Verify a boolean condition:QVERIFY2
Verify with a custom failure message:QTEST
Test a function with data-driven testing:QSKIP
Skip a test conditionally:Test Organization
Organize tests into logical groups:Testing Guidelines
Unit Tests
Write focused unit tests that:- Test one component or function at a time
- Are independent of other tests
- Run quickly
- Have clear, descriptive names
- Cover both normal and edge cases
Test Coverage
Aim to test:- Happy path: Normal, expected usage
- Edge cases: Boundary conditions, empty inputs, maximum values
- Error cases: Invalid inputs, null pointers, out-of-bounds
- Regression cases: Previously fixed bugs
Example: Comprehensive Test Coverage
Test Naming
Use descriptive test names that indicate what is being tested:Assertions and Expectations
- Use appropriate assertion macros
- Include descriptive failure messages
- Test exact values when possible
- Verify both positive and negative cases
Test Data
Use realistic test data:Continuous Integration
Zeal uses GitHub Actions for continuous integration:- Tests run automatically on all pull requests
- Tests run on multiple platforms (Linux, Windows, macOS)
- Build status is visible in pull requests
Build Check Workflow
The.github/workflows/build-check.yaml workflow:
- Builds Zeal on all platforms
- Runs the full test suite
- Reports failures to pull request authors
Debugging Tests
Run Tests in Debug Mode
Build in debug mode for better debugging:Run Single Test
Run a specific test directly:Qt Test Options
Qt Test supports various command-line options:Using a Debugger
Run tests under a debugger:Adding New Tests
To add a new test suite:-
Create test directory:
src/libs/yourmodule/tests/ -
Write test file:
your_test.cpp
- Create CMakeLists.txt:
- Update parent CMakeLists.txt:
- Build and run:
Best Practices
Do:
- Write tests for all new code
- Run tests before submitting pull requests
- Keep tests simple and focused
- Use descriptive test names
- Test edge cases and error conditions
- Update tests when fixing bugs
- Document complex test scenarios
Don’t:
- Skip failing tests (fix them instead)
- Write tests that depend on external resources
- Write tests that depend on execution order
- Leave commented-out test code
- Write tests that take too long to run
- Ignore test failures in CI
Resources
Summary
Key testing practices:- Enable tests with
BUILD_TESTING=ON - Run tests with
ctest --test-dir build - Write focused, independent unit tests
- Use Qt Test framework macros (
QCOMPARE,QVERIFY) - Test happy paths, edge cases, and error conditions
- Include regression tests for bug fixes
- Run tests before submitting pull requests