Tutorial paso a paso · Test Driven Development

Emulador NES por TDD

Construye un emulador de Nintendo Entertainment System desde cero en Python siguiendo 356 lecciones guiadas por tests.

Autor: linkfy · 14 capítulos · 356 lecciones

Qué es este tutorial

Este es un proyecto inicial que contiene únicamente los tests. No incluye a propósito el emulador terminado: el directorio tests/ es el currículo. Cada test numerado explica por qué importa el siguiente comportamiento, qué archivo de producción crear o actualizar y la implementación mínima esperada en ese punto.

Este tutorial toma la ruta deliberada, no la rápida.

Los primeros capítulos construyen y verifican la CPU, la memoria, el cartucho y las bases de la PPU. Los gráficos del juego y el frontend interactivo llegan más tarde, cuando los componentes que los soportan se han ganado su lugar mediante tests. No esperes un juego en pantalla en las primeras lecciones; espera entender por qué funciona cuando finalmente aparece.

Puesta en marcha

  1. 1. Clona el repositorio

    git clone https://github.com/linkfy/nes-emulator-tutorial-tdd
    cd nes-emulator-tutorial-tdd
  2. 2. Instala uv y crea el entorno bloqueado

    No ejecutes uv init dentro del repositorio: el proyecto ya está inicializado. Desde la raíz del proyecto, instala las dependencias fijadas en uv.lock.

    uv --version
    uv sync

    docs.astral.sh/uv

  3. 3. Abre la lección 001 y ejecuta solo ese test

    Lee la documentación del módulo de principio a fin antes de escribir código de producción. Después ejecuta únicamente esa lección:

    uv run pytest tests/chapter_01_cpu/test_001_initial_files.py -v
  4. 4. Repite el ciclo Rojo → Verde → Refactor

    Avanza un test numerado a la vez. Cada lección completada debe permanecer verde antes de seguir. Ejecuta solo los tests completados; no ejecutes capítulos futuros todavía.

    Cuando termines la lección 356, ejecuta la suite completa:

    uv run pytest

El ciclo TDD

Rojo

Ejecuta el test de la lección y observa cómo falla.

Verde

Escribe la implementación más pequeña que lo hace pasar.

Refactor

Limpia el código manteniendo verdes todos los tests anteriores.

Marcadores en el código

Los ejemplos de las lecciones pueden usar NEW LINE / NEW BLOCK para código nuevo, UPDATED LINE / UPDATED BLOCK para cambios, DELETED LINE / DELETED BLOCK para código obsoleto y ... donde el código existente permanece igual.

Índice de capítulos

Catorce capítulos y 356 lecciones ordenadas. Usa los rangos para saber dónde estás y qué viene después.

01CPUCPU, RAM, bus, modos de direccionamiento, instrucciones, flags y validaciónTests 001211 · 211 lecciones
02Carga de ROMsParseo iNES, cartuchos, Mapper 000 y ejecución de ROMsTests 212223 · 12 lecciones
03Memoria PPU y gráficosRegistros de la PPU, bus de la PPU, VRAM, datos CHR y decodificación gráficaTests 224258 · 35 lecciones
04Temporización PPU y VBlankTemporización de la PPU, VBlank, NMI y coordinación CPU/PPUTests 259269 · 11 lecciones
05Pipeline de renderizadoPipeline de renderizado puro, framebuffer y utilidades pygameTests 270287 · 18 lecciones
06Arranque de ROMPreparación del arranque de ROMs, no-ops de la APU y OAM DMATests 288289 · 2 lecciones
07Mando de entradaProtocolo del mando NES e integración de $4016Tests 290293 · 4 lecciones
08Main manualBucle manual de ROM, frontend pygame, teclado y erroresTests 294298 · 5 lecciones
09Renderizado de spritesDecodificación, renderizado, prioridad y composición de spritesTests 299314 · 16 lecciones
10RendimientoInforme de FPS, subida rápida del framebuffer, PyPy y ritmo inicialTests 315318 · 4 lecciones
11Sprite Zero HitDetección de sprite-zero-hit e integración temporalTests 319323 · 5 lecciones
12MirroringMirroring de nametables del cartuchoTests 324327 · 4 lecciones
13ScrollingComposición horizontal del viewport y scroll temporizadoTests 328353 · 26 lecciones
14OptimizacionesCachés de renderizado inmutables y ritmo de frames por deadline absolutoTests 354356 · 3 lecciones

ROMs manuales

Algunas lecciones avanzadas incluyen comprobaciones manuales con ROMs reales obtenidas legalmente (por ejemplo Super Mario Bros. o Mario Bros.). Solo se necesitan cuando una lección llega a un punto de control manual.