Skip to main content

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:
Run unit tests manually:
List all tests:
After modifying a test file, run cmake --build build. For non-test file changes, use cmake --build build --target test_bitcoin to recompile only what’s needed.

Running Individual Tests

The test_bitcoin runner accepts Boost framework arguments:

Passing bitcoind Arguments

Use -- to separate test runner and bitcoind arguments:
The -printtoconsole=1 sends debug logging (normally only in debug.log) to standard output.

Test Data Directory

Running test_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:
This prevents the directory from being deleted after tests complete, useful for inspecting debug.log.

Adding Unit Tests

To add new unit tests:
  1. Add file to src/test/CMakeLists.txt or src/wallet/test/CMakeLists.txt (wallet tests)
  2. Follow naming convention: <source_filename>_tests.cpp
  3. Wrap tests in test suite: <source_filename>_tests
  4. Add test cases using BOOST_AUTO_TEST_CASE functions
Example pattern:

GUI Unit Tests

Run GUI tests manually:
Add new GUI tests to src/qt/test/ directory and src/qt/test/test_main.cpp.

Logging in Unit Tests

View test output:
Log from within tests using Boost message methods:

Debugging Unit Tests

Launch with debugger:
For segmentation faults:
Or use valgrind. To generate core dumps:

Functional Tests

Prerequisites

Build Bitcoin Core first (see building instructions).

Dependencies

ZMQ tests - Install python ZMQ library:
IPC tests - Install python IPC library:
Windows: Set UTF-8 mode:

Running Functional Tests

Run individual test:
Run via test runner:
Run multiple tests:
Run all wallet tests (from appropriate directory):
Run full regression suite:
Run all tests including extended:
By default, up to 4 tests run in parallel. Specify job count with --jobs=n.

Backwards Compatibility Tests

Download previous release binaries:
Then run tests normally - they’ll use the downloaded binaries.

Speed Up Tests with RAM Disk

Create RAM disk for cache and tmp directories: Linux (4 GiB RAM disk at /mnt/tmp/):
macOS (4 GiB RAM disk at /Volumes/ramdisk/):
RAM disk size depends on parallel jobs. --jobs=100 might need 4 GiB, while --jobs=32 needs only ~2.5 GiB.

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 in build/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)
Log file locations:
  • <test data directory>/test_framework.log
  • <test data directory>/node<node number>/regtest/debug.log
Change console log level:
Combine logs:
Trace RPC calls:
Preserve test data:

Attaching a Debugger

Attach Python debugger:
Attach to bitcoind process:
Disable RPC timeouts:

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