Overview
Csound has a comprehensive testing framework covering unit tests, integration tests, and regression tests. Tests help ensure code quality, prevent regressions, and document expected behavior.Test categories
Unit tests (tests/c)
Unit tests are written in C/C++ using the GoogleTest framework. They test individual functions and components in isolation. Location:tests/c/
Framework: GoogleTest (GTest)
Purpose: Test compiler internals, API methods, and core functionality
Examples:
csound_orc_compile_test.cpp- Compiler testscsound_type_system_test.cpp- Type system testschannel_tests.cpp- Channel API testscsound_circular_buffer_test.cpp- Circular buffer tests
Integration tests (tests/commandline)
Integration tests use CSD (Csound Document) files executed by a Python test runner. They test the complete system with real Csound code. Location:tests/commandline/
Runner: Python script (test.py)
Purpose: Test opcodes, compiler, and runtime behavior
File format: .csd files with embedded Csound code
Regression tests (tests/regression)
A collection of tests for previously reported bugs to ensure they remain fixed. Location:tests/regression/
Purpose: Prevent regression of fixed bugs
Soak tests (tests/soak)
Large-scale tests that run most examples from the Csound manual. Location:tests/soak/
Purpose: Comprehensive testing using manual examples
Features:
- MD5 checksums for audio output comparison
- Diff for text output comparison
- Detects changes since previous run
Building tests
Enable test building
Tests are not built by default. Enable them with theBUILD_TESTS option:
Build requirements
- GoogleTest: Required for unit tests (auto-installed with vcpkg)
- Static library: Unit tests link against the static Csound library
- Python: Required for integration test runner
Build with vcpkg
Running tests
All tests
Run both unit and integration tests:Unit tests only
Run GoogleTest unit tests:CTest options
Verbose output:Integration tests (CSD tests)
Run CSD integration tests:Manual execution
Run the Python test runner directly:Test runner options
--csound-executable: Path to Csound binary--source-dir: Test source directory--opcode7dir64: Opcode plugin directory--verbose: Enable verbose output--runtime-environment: Runtime wrapper (e.g.,wine, Node.js)
Platform-specific testing
Linux
macOS
Windows (MSVC)
MinGW with Wine
Emscripten
Writing tests
Writing unit tests
Unit tests use GoogleTest. Add new test files totests/c/CMakeLists.txt:
Example unit test
GoogleTest assertions
EXPECT_EQ(a, b)- Expect equalityEXPECT_NE(a, b)- Expect inequalityEXPECT_TRUE(condition)- Expect trueEXPECT_FALSE(condition)- Expect falseASSERT_*variants - Fatal assertions (stop test on failure)
Writing integration tests
Integration tests are CSD files placed intests/commandline/.
Example CSD test
Test organization
Organize tests by category:tests/commandline/opcodes/- Opcode teststests/commandline/errors/- Error handling teststests/commandline/regression/- Regression tests
Writing regression tests
When fixing a bug:- Create a minimal test case that reproduces the bug
- Add the test to
tests/regression/ - Verify the test fails before the fix
- Verify the test passes after the fix
Continuous integration testing
All tests run automatically on CI for every pull request. See the CI/CD guide for details.CI test coverage
CI runs tests on:- Linux: Ubuntu with apt-get and vcpkg
- macOS: Homebrew and installer builds
- Windows: MSVC 64-bit and 32-bit, MinGW
- Mobile: iOS and Android
- Web: WebAssembly/Emscripten
- Embedded: ARM Cortex-M7 bare metal
CI test commands
CI uses these commands to run tests:Test configuration
CMakeLists.txt for unit tests
Unit tests are configured intests/c/CMakeLists.txt:
CMakeLists.txt for integration tests
Integration tests are configured intests/commandline/CMakeLists.txt:
Debugging test failures
Run single unit test
Run with verbose output
Debug CSD test
Run a specific CSD file directly:Address sanitizer
On macOS in Debug mode, address sanitizer is enabled by default:Best practices
Test isolation
- Each test should be independent
- Clean up resources (destroy Csound instances)
- Don’t rely on test execution order
Test coverage
- Test both success and failure paths
- Test edge cases and boundary conditions
- Test error handling
Test maintenance
- Keep tests simple and focused
- Use descriptive test names
- Update tests when behavior changes
- Remove obsolete tests
Performance
- Keep unit tests fast (milliseconds)
- Use minimal CSD files for integration tests
- Avoid unnecessary file I/O