Software · Intermediate
Software Testing and QA Automation
Learn to test software the way professionals do — the test pyramid, pytest, fixtures, mocking, coverage, property-based testing, flaky-test hygiene, and gating a build on a fail-closed CI contract.
About this course
Working software is not software that ran once; it is software you can change without fear. The thing that removes the fear is a test suite you trust. This course teaches how to build one. The concepts are general to every language — the test pyramid; unit, integration and end-to-end tests; test-driven development; fixtures; test doubles; coverage; property-based testing; flaky-test hygiene; and gating a build on tests — and the vehicle is Python 3.12 with pytest, because it is concise enough to keep the ideas in view. You test one small system that you are given at the start: `quoting`, a tiny quoting engine with a pure pricing layer, a SQLite-backed catalog, a tax-rate lookup over HTTP, an orchestration layer and a command-line front end. Each layer is chosen to teach a technique. **Lessons 1–2** cover why we test, the test pyramid, and your first pytest tests, assertions and test selection. **Lessons 3–4** structure a suite with fixtures, `conftest.py`, setup/teardown and parametrised, data-driven tests. **Lessons 5–6** isolate the code under test with fakes, mocks and patching — and when *not* to mock — then test a real integration boundary (a database) with disposable, per-test resources. **Lessons 7–9** measure line and branch coverage and its limits, find edge cases with property-based testing (hypothesis), and remove flakiness so a suite is deterministic and fast. **Lesson 10** turns the suite into a QA gate: a fail-closed `ci.sh` that lints, tests, enforces a coverage floor and writes a JUnit report. **Final project.** You are handed a small application that ships with five planted defects. You write a test suite that catches every one, reach a branch-coverage target, gate the app on a `ci.sh`, then fix the bugs and prove the suite green — the everyday loop of QA automation. Everything runs on your lab machine `linux01` (Ubuntu 24.04, Python 3.12) with pytest, pytest-cov and hypothesis from PyPI. No test touches a real network. This is a learning pathway toward quality-engineering and backend-development work; it makes no promise of employment or any vendor certification, and completion earns an Ultiblob Certificate of Completion.
- Content time
- 9 h 20 min
- Lessons
- 10
- Certificate
- Yes
- on completion
Lesson 1 is free. Enroll in a career path to access its full courses.
Lesson 1 is a free preview — read it without an account.

Outline
Lessons
Lesson 1: Why we test, and the test pyramidFree preview
What automated tests buy you, the unit/integration/end-to-end pyramid, what a good test looks like, and a working pytest environment.
45 minLesson 2: Your first pytest tests
Write tests with plain assert, run and select them, read pytest's assertion introspection, and assert that errors are raised.
55 minLesson 3: Fixtures and test structure
Share setup with fixtures and conftest.py, get fresh resources per test with tmp_path, tear down with yield, and choose a fixture scope.
55 minLesson 4: Parametrised and data-driven tests
Run one test body over many inputs with parametrize, name the cases with ids, cover edge cases, and mark a known-failing case with xfail.
50 minLesson 5: Test doubles — mocking, patching and fakes
Replace an external dependency with a fake, a Mock or a patch, patch where a name is used, use monkeypatch, and know when not to mock.
1 h 5 minLesson 6: Integration testing at a boundary
Test real components together — code plus a real SQLite database — using disposable, per-test resources, while faking only the true external boundary.
1 hLesson 7: Coverage, and what it tells you
Measure line and branch coverage with pytest-cov, read the report, set a floor — and see why 100% coverage does not mean correct.
55 minLesson 8: Property-based testing
Assert properties that hold for all inputs and let hypothesis generate cases to falsify them, shrinking failures to a minimal counterexample.
1 hLesson 9: Flaky tests, isolation and determinism
Find and fix tests that pass sometimes and fail others — shared state, the clock, randomness and order — and keep the suite fast.
55 minLesson 10: QA in the pipeline
Turn the suite into a fail-closed ci.sh gate — lint, test, coverage floor, JUnit report — and read it as the same contract a CI server runs.
1 h
Where it leads