Software Testing Tutorial with Examples.
Software testing tutorial from first principles: the test pyramid, test doubles, coverage that means something, and flake control.
Beginner
Start here — no prior experience needed
Intermediate
For developers with core concepts down
Test Doubles & Dependency Boundaries (Intermediate)
When to use a stub, a fake or a mock, shown with Jest tests against a repository interface, plus how an over-specified mock breaks on a random id.
Boundary-Value Analysis: The Bug Equivalence Partitioning Misses
Test one value per equivalence class and a real off-by-one bug slips through. Test the exact edges instead and the same bug fails loudly.
Line Coverage Lies: Why Branch Coverage Catches More
A test suite hits 100% line coverage and still misses a real bug. Turning on branch coverage shows exactly which decision path was never exercised.
Test-Driven Development: Red, Green, Refactor with pytest
Build a slugify function test-first: real red runs, a faked green that a second test breaks, and a refactor the suite proves safe, or catches.
Advanced
Production-grade patterns for experienced engineers
Flaky Tests Diagnosis & Stabilization (Advanced)
Measure a flaky Jest test over repeated runs, then fix it with seeded randomness, fake timers, awaiting completion and isolated state, not sleeps.
Mutation Testing: When 100% Coverage Still Isn't Enough
A test suite with full branch coverage still lets 3 injected bugs slip through undetected. Mutation testing finds exactly which ones, and why.
Load Testing with Locust: Percentiles, the Knee and a CI Gate
Load-test a real API with Locust in Docker: why the average lies, where latency starts climbing, why user counts mislead, and a p95 budget that fails CI.
Also part of Software Testing
Taught in other topics. Each link opens the lesson in its home topic.
Testing Python Code
Write and run pytest tests: assertions, exceptions, fixtures, parametrize, mocks, coverage, async tests and unittest, with real pytest output for each.
Unit Testing with JUnit 5 and Mockito
Learn JUnit 5 and Mockito by running real tests: lifecycle, assertions, assertAll, parameterized tests, stubbing, verify and ArgumentCaptor.
Testing JavaScript with Jest and Vitest
Learn how to write reliable unit tests in JavaScript using Jest and Vitest — from basic assertions to mocking, async tests, and code coverage.
Testing in Go
Go testing run for real: a failing test, table-driven subtests, t.Error vs t.Fatal, httptest, examples, fuzzing that finds a bug, benchmarks, and coverage.
Testing in Rust
Write unit tests, integration tests, and doc tests in Rust using cargo test.
Testing with MUnit and ScalaCheck
Run tests with one command, read a failure diff that actually helps, test futures without blocking, and let property-based testing find edge cases.
Contract Testing with OpenAPI, and Running in CI
Turn an OpenAPI document into the same jsonschema validation from earlier in this track, catch a proposed API change that breaks the contract, and wire the suite into GitHub Actions with a JUnit report.
Your First Playwright Test
Install Playwright, write an end-to-end test against a real page, and read the runner's output — including what a failing assertion actually tells you.
Flaky Tests: Staleness, Retries, and CI
Fix StaleElementReferenceException properly, find the five causes of tests that only fail in CI, and use retries as a signal rather than a cure.
Testing Data Pipelines
Write tests for a transform function, then let a 'harmless' refactor slip through code review and see the test suite catch it instead of production.
terraform test: Catching a Wrong Assertion, Not Just a Wrong Plan
Terraform's test runner checks real plans and applies from .tftest.hcl files. It catches a bug in the test, a deleted validation, and mocks a provider.
Testing TypeScript
Test TypeScript with Vitest: typed fixtures, vi.mock and vi.mocked, spies, fake timers, expectTypeOf type tests, and Jest with ts-jest — with real runs.