Learn Testing & Software Quality — from newbie to expert

A guided path from "why did that break?" to confident quality engineering. Understand what bugs really are and what they cost, write your first unit tests in Go, grow into integration and regression testing, master the tooling that keeps a codebase healthy, learn to debug methodically — and then apply all of it the way GopherTrunk does, where no fix lands without a test that failed first.

Every module on this site teaches you to build something. This one teaches you to know whether what you built actually works — and to keep it working while it changes. Testing is the difference between “it seemed fine when I ran it” and “I can show you it’s correct, and I’ll know within minutes if it ever stops being correct.” That skill compounds: it makes you faster, not slower, because you spend your time building instead of re-breaking and re-fixing the same things.

Who this is for. Anyone who writes code — or wants to — and has felt the sting of something breaking that used to work. It pairs naturally with the Programming in Go module (the examples here are Go) and the Git & GitHub module (reviews, checks, and bisecting all live there too), but the first units assume nothing beyond basic programming. By the end you’ll be reading and writing tests the way a working engineer does.

How the path works. Six units climb from why to how to for real. The first covers why software breaks and what quality thinking looks like. The second and third teach the tests themselves — unit tests in Go, then integration, regression, and generative testing. The fourth is the tooling that guards a codebase between releases: linters, formatters, review, and CI. The fifth is debugging — reproducing, reading evidence, bisecting, and finding root causes. The last unit applies all of it to GopherTrunk itself: replay tests that decode recorded radio captures, the traps a self-consistent test can hide, and the failing-first discipline under which no fix lands without a test that failed before it. Mark lessons complete as you go — your progress is saved in your browser. New here? Start with lesson 1: Why does software break?

Unit 1 — Why Software Breaks

Bugs, what they cost, and the mindset shift from 'it seems to work' to 'I can show it works.'

  1. Why does software break? Software fails because people encode assumptions — complexity, change, and edge cases turn small oversights into visible failures. beginner 8 min
  2. What is a bug? Mistake, defect, failure — how a wrong line of code becomes a wrong behavior, and why the distinction shapes how you hunt them. beginner 7 min
  3. What does a bug cost? The later a bug is found, the more it costs — from a red test on your laptop to a field failure, with famous disasters as waypoints. beginner 7 min
  4. What is testing? Manual vs automated testing, verification vs validation, and the test pyramid — the map for everything this module covers. beginner 8 min
  5. The testing mindset Thinking adversarially about your own code — assume it's wrong, try to break it, and turn "it seems to work" into evidence. beginner 7 min

Unit 2 — Unit Testing Fundamentals

The smallest, fastest tests — how to write them well in Go and what coverage really tells you.

  1. What is a unit test? One small piece of code, tested in isolation, fast enough to run thousands of times a day — the foundation of the pyramid. beginner 7 min
  2. Anatomy of a test Arrange, act, assert — the three-part shape of every good test, plus naming and the one-behavior-per-test rule. beginner 8 min
  3. Your first Go test Write a _test.go file, run go test, and read a failure — the complete edit-test loop with nothing but the standard library. beginner 9 min
  4. Table-driven tests Go's signature testing idiom — one test body, a table of cases, and subtests that name each row. intermediate 8 min
  5. Fakes, stubs, and mocks Test doubles stand in for slow or unpredictable dependencies — and Go's interfaces make swapping them in natural. intermediate 9 min
  6. Code coverage What coverage measures, how to read go test -cover, and why 100% is the wrong goal. intermediate 7 min

Unit 3 — Beyond the Unit

Integration, end-to-end, regression, and generative testing — proving whole systems, not just pieces.

  1. Integration tests Testing real pieces wired together — databases, files, networks — and the trade of realism against speed. intermediate 8 min
  2. End-to-end tests Drive the whole system the way a user would — the most convincing tests, and the most expensive ones. intermediate 8 min
  3. Regression tests & failing first Every bug fix ships with a test that failed before the fix — the discipline that stops bugs from coming back. intermediate 8 min
  4. Golden files & fixtures Recorded inputs and expected outputs — how captured data turns messy real-world behavior into repeatable tests. intermediate 8 min
  5. Property-based testing Instead of hand-picking examples, state a property that must always hold and let the computer hunt for a counterexample. intermediate 8 min
  6. Fuzzing Throw randomized, mutated inputs at your code until it crashes — Go's built-in fuzzer and why parsers need it most. intermediate 8 min

Unit 4 — Quality Tooling

Linters, formatters, code review, and CI — the machinery that keeps a codebase healthy between releases.

  1. Linters & static analysis Tools that read your code without running it — go vet, staticcheck, and the bug classes they catch for free. intermediate 8 min
  2. Formatters & style gofmt ends formatting debates by making one style automatic — and why that's a quality tool, not a cosmetic one. beginner 6 min
  3. Code review A second pair of eyes before code merges — how to review, how to be reviewed, and what review catches that tests can't. beginner 8 min
  4. Continuous integration Every push builds and tests automatically — pipelines, checks on pull requests, and why CI is the team's shared safety net. intermediate 9 min
  5. Flaky tests Tests that pass sometimes are worse than tests that fail always — where flakiness comes from and why "flake" is not a root cause. intermediate 8 min
  6. Required checks & branch protection Which CI jobs actually gate a merge — and how a green checkmark can hide a red build in a job nobody made required. intermediate 7 min

Unit 5 — Debugging & Diagnosis

When something is broken: reproduce it, read the evidence, and find the real cause.

  1. Reproducing a bug A bug you can reproduce on demand is already half fixed — minimal reproductions and why "works on my machine" is a clue, not a verdict. intermediate 8 min
  2. Reading error messages & stack traces Errors and panics are structured evidence — how to read a Go stack trace from the top and find the line that matters. beginner 8 min
  3. Print debugging & logging The humble print statement, done well — and how structured logs turn one-off debugging into a permanent diagnostic instrument. beginner 8 min
  4. Using a debugger Pause a live program, inspect its state, step line by line — Delve for Go, and when a debugger beats prints. intermediate 9 min
  5. Bisecting history git bisect turns "it broke sometime this month" into the exact commit, in a dozen automatic steps. intermediate 8 min
  6. Root-cause analysis Keep asking why until the answer would have prevented the bug — fixing symptoms leaves the cause free to strike again. intermediate 8 min

Unit 6 — Testing GopherTrunk

Apply it all to a real codebase: replay tests, capture-gated verification, and the traps GopherTrunk learned the hard way.

  1. The make vet test gate GopherTrunk's rule that vet plus unit tests must be green before any commit — what runs, and why the gate is non-negotiable. intermediate 7 min
  2. Replay: testing a radio without a radio Recorded IQ captures let GopherTrunk test a whole radio decoder deterministically — the golden-file idea at system scale. intermediate 9 min
  3. The self-consistent synthetic trap A test whose encoder and decoder share the same wrong assumption passes while the real world fails — GopherTrunk's most instructive bug pattern. advanced 9 min
  4. Capture-gated verification A fix isn't verified until it works against real captured data — why GopherTrunk refuses to close a bug on a green synthetic test alone. advanced 8 min
  5. Write your first regression test Walk the full failing-first loop on a real bug — reproduce, write the test that fails, fix, watch it pass, and ship both together. advanced 10 min
  1. Glossary of testing terms Plain-language definitions for every term in the module — unit test, assertion, fixture, mock, coverage, regression, CI, flaky test, fuzzing, bisect, root cause, and more — cross-linked to the lessons.