Step-by-step tutorial · Test Driven Development

NES Emulator by TDD

Build a Nintendo Entertainment System emulator from scratch in Python by following 356 test-driven lessons.

Author: linkfy · 14 chapters · 356 lessons

What this tutorial is

This is a tests-only starter project. It intentionally does not contain the completed emulator: the tests/ directory is the curriculum. Each numbered test explains why the next behavior matters, which production file to create or update, and the smallest implementation expected at that point.

This tutorial takes the deliberate route, not the fast route.

The first chapters build and verify the CPU, memory, cartridge, and PPU foundations. Game graphics and the interactive frontend arrive later, after the components that support them have earned their place through tests. Do not expect a game on screen in the first few lessons; expect to understand why it works when it finally appears.

Getting started

  1. 1. Clone the repository

    git clone https://github.com/linkfy/nes-emulator-tutorial-tdd
    cd nes-emulator-tutorial-tdd
  2. 2. Install uv and create the locked environment

    Do not run uv init inside the repository: the project is already initialized. From the project root, install the dependencies pinned in uv.lock.

    uv --version
    uv sync

    docs.astral.sh/uv

  3. 3. Open lesson 001 and run only that test

    Read its module-level documentation from beginning to end before writing production code. Then run only that lesson:

    uv run pytest tests/chapter_01_cpu/test_001_initial_files.py -v
  4. 4. Repeat Red → Green → Refactor

    Move one numbered test at a time. Every completed lesson must remain green before you move forward. Run completed tests only; do not run future chapters yet.

    After lesson 356, run the complete suite:

    uv run pytest

The TDD loop

Red

Run the lesson test and watch it fail.

Green

Write the smallest implementation that makes it pass.

Refactor

Clean up while keeping every earlier test green.

Markers in code

Lesson examples may use NEW LINE / NEW BLOCK for code to add, UPDATED LINE / UPDATED BLOCK for code to change, DELETED LINE / DELETED BLOCK for obsolete code and ... where existing code stays unchanged.

Curriculum map

Fourteen chapters and 356 ordered lessons. Use the ranges to see where you are and what comes next.

Manual ROMs

Some later lessons include manual checks with legally obtained real ROMs (for example Super Mario Bros. or Mario Bros.). They are only needed when a lesson reaches a manual checkpoint.