Overview
Bitcoin Core includes comprehensive testing infrastructure:- Unit tests - Test individual components using Boost Test framework
- Functional tests - Test bitcoind and utilities through RPC and P2P interfaces
- Fuzz tests - Discover edge cases and vulnerabilities (see Fuzzing guide)
- Lint tests - Static analysis checks for code quality
Unit Tests
Building and Running
Unit tests are automatically compiled if dependencies are met and tests weren’t explicitly disabled. Run all unit tests:Running Individual Tests
Thetest_bitcoin runner accepts Boost framework arguments:
Passing bitcoind Arguments
Use-- to separate test runner and bitcoind arguments:
-printtoconsole=1 sends debug logging (normally only in debug.log) to standard output.
Test Data Directory
Runningtest_bitcoin creates a temporary data directory at test_common bitcoin/ within the system’s temp directory. Contents vary by test but always include a debug.log file.
Specify custom data directory with -testdatadir:
debug.log.
Adding Unit Tests
To add new unit tests:- Add file to
src/test/CMakeLists.txtorsrc/wallet/test/CMakeLists.txt(wallet tests) - Follow naming convention:
<source_filename>_tests.cpp - Wrap tests in test suite:
<source_filename>_tests - Add test cases using
BOOST_AUTO_TEST_CASEfunctions
GUI Unit Tests
Run GUI tests manually:src/qt/test/ directory and src/qt/test/test_main.cpp.
Logging in Unit Tests
View test output:Debugging Unit Tests
Launch with debugger:Functional Tests
Prerequisites
Build Bitcoin Core first (see building instructions).Dependencies
ZMQ tests - Install python ZMQ library:Running Functional Tests
Run individual test:By default, up to 4 tests run in parallel. Specify job count with
--jobs=n.Backwards Compatibility Tests
Download previous release binaries:Speed Up Tests with RAM Disk
Create RAM disk for cache and tmp directories: Linux (4 GiB RAM disk at/mnt/tmp/):
/Volumes/ramdisk/):
Troubleshooting Functional Tests
Resource Contention
Port conflicts can occur if another bitcoind process is running. On Linux, the framework warns about this. Kill zombie bitcoind processes:These commands kill ALL bitcoind processes on the system. Don’t use if running non-test bitcoind instances.
Data Directory Cache
A pre-mined blockchain with 200 blocks is generated and cached inbuild/test/cache on first run. If cache gets corrupted:
Test Logging
Logging levels: DEBUG, INFO, WARNING, ERROR, CRITICAL Default behavior:- Via test_runner: All logs to
test_framework.log, none to console - Direct run: All logs to
test_framework.log, INFO+ to console - CI: No console output unless test fails (then dumps all logs)
<test data directory>/test_framework.log<test data directory>/node<node number>/regtest/debug.log
Attaching a Debugger
Attach Python debugger:Profiling with perf
Generate performance profiles on Linux:Lint Tests
Lint tests perform static analysis checks. See test/lint/README.md for details.Best Practices
Test Coverage
- Write tests for all new features and bug fixes
- Aim for high code coverage (see Developer Notes for coverage tools)
- Unit tests for individual component logic
- Functional tests for integration and end-to-end scenarios
Test Organization
- One unit test file per source file:
<source>_tests.cpp - One test suite per source file:
<source>_tests - Descriptive test case names that explain what’s being tested
- Group related functional tests in same directory
Writing Good Tests
- Tests should be deterministic and repeatable
- Avoid dependencies between test cases
- Use appropriate assertions with clear failure messages
- Test both success and failure paths
- Test edge cases and boundary conditions
- Keep tests focused and concise