Testing
El testing no es opcional en Bitcoin Core — es un requisito de primera clase. Cada pull request debe incluir tests apropiados. El proyecto tiene múltiples capas de testing, cada una detectando diferentes tipos de bugs.
Capas de Testing
Tests Unitarios (C++)
Ubicados en src/test/, estos prueban funciones y clases individuales de forma aislada:
# Compilar y ejecutar tests unitarios
cmake --build build
ctest --test-dir build
# Ejecutar suite de tests específica
./build/src/test/test_bitcoin --run_test=script_tests
# Listar suites de tests disponibles
./build/src/test/test_bitcoin --list_content
Los tests unitarios usan el framework Boost.Test:
BOOST_AUTO_TEST_SUITE(example_tests)
BOOST_AUTO_TEST_CASE(basic_check)
{
CTransaction tx;
BOOST_CHECK(tx.vin.empty());
BOOST_CHECK(tx.vout.empty());
}
BOOST_AUTO_TEST_SUITE_END()
Tests Funcionales (Python)
Ubicados en test/functional/, estos levantan nodos reales de Bitcoin Core y prueban el comportamiento de extremo a extremo:
# Ejecutar toda la suite de tests funcionales
test/functional/test_runner.py
# Ejecutar test específico con logging
test/functional/feature_block.py --loglevel=debug
# Ejecutar tests en paralelo
test/functional/test_runner.py -j8
Los tests funcionales son la forma principal de probar cambios a nivel de protocolo. Simulan condiciones reales de red con múltiples nodos.
Fuzz Testing
El fuzz testing alimenta datos aleatorios o semi-aleatorios a funciones de parsing para encontrar crashes, cuelgues y comportamiento indefinido:
# Compilar con soporte de fuzzing
cmake -B build -DSANITIZERS=fuzzer
cmake --build build
# Ejecutar un objetivo de fuzz
./build/src/test/fuzz/deserialize_block
# Ejecutar con un corpus
./build/src/test/fuzz/deserialize_block corpus/
Bitcoin Core tiene cientos de objetivos de fuzz cubriendo deserialización, parsing de scripts, manejo de mensajes de red y más. El proyecto OSS-Fuzz ejecuta fuzz testing continuo sobre Bitcoin Core.
Linting
Análisis estático y verificaciones de estilo se ejecutan en CI:
# Ejecutar todos los linters
test/lint/run-lint.sh
# Verificaciones específicas
test/lint/lint-circular-dependencies.py
test/lint/lint-includes.py
Infraestructura de CI
Cada pull request pasa por CI automatizado:
| Sistema | Qué Verifica |
|---|---|
| GitHub Actions | Compilación en múltiples plataformas, ejecución de tests |
| Cirrus CI | Compilaciones en macOS, ejecución de sanitizers |
| OSS-Fuzz | Fuzz testing continuo |
| Guix builds | Compilaciones binarias reproducibles |
Sanitizers
El CI de Bitcoin Core usa sanitizers de LLVM para detectar bugs de memoria e hilos:
- ASan (AddressSanitizer) — Desbordamientos de buffer, uso después de liberar
- UBSan (UndefinedBehaviorSanitizer) — Desbordamiento de enteros, desreferencia de puntero nulo
- TSan (ThreadSanitizer) — Condiciones de carrera de datos
- MSan (MemorySanitizer) — Lecturas de memoria no inicializada
# Compilar con sanitizers
cmake -B build -DSANITIZERS="address;undefined"
cmake --build build
Escribir Buenos Tests
Al contribuir a Bitcoin Core, sigue estas guías de testing:
- Prueba el comportamiento, no la implementación — Los tests deben verificar qué hace el código, no cómo lo hace
- Prueba casos límite — Entradas vacías, valores máximos, datos malformados
- Prueba modos de falla — Asegúrate de que las entradas inválidas se rechacen correctamente
- No pruebes funcionalidad del framework — Confía en Boost.Test y el framework de Python
- Mantén los tests determinísticos — Evita dependencias de tiempo y fallos aleatorios