Saltar al contenido principal

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:

SistemaQué Verifica
GitHub ActionsCompilación en múltiples plataformas, ejecución de tests
Cirrus CICompilaciones en macOS, ejecución de sanitizers
OSS-FuzzFuzz testing continuo
Guix buildsCompilaciones 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:

  1. Prueba el comportamiento, no la implementación — Los tests deben verificar qué hace el código, no cómo lo hace
  2. Prueba casos límite — Entradas vacías, valores máximos, datos malformados
  3. Prueba modos de falla — Asegúrate de que las entradas inválidas se rechacen correctamente
  4. No pruebes funcionalidad del framework — Confía en Boost.Test y el framework de Python
  5. Mantén los tests determinísticos — Evita dependencias de tiempo y fallos aleatorios

Lectura Recomendada