On this page
  1. What you’ll build
  2. Step 1 — Write the function
  3. Step 2 — Write the test
  4. Step 3 — Run the tests
  5. Step 4 — Confirm the test actually guards
  6. Step 5 — Run it in CI
  7. Where AI coding assistants get this wrong
  8. Checklist
  9. FAQ
    1. What is pytest?
    2. What makes a good unit test?
    3. What is the difference between a unit test and an integration test?
  10. Related topics
  11. Sources
tutorial

How to Write Your First Unit Test

Write your first unit test in Python with pytest: a real function, a real test, and the red-green cycle. A first-principles tutorial for beginners.

Quick answer

  • A unit test checks one function’s behavior in isolation, with known inputs and an expected output.
  • In Python, pytest turns a plain function whose name starts with test_ into a test.
  • You know it works when the test passes — and, just as importantly, fails when the code is wrong.

What you’ll build

A unit test for one small function: a price calculator that applies a discount. You’ll write the test, watch it pass, then break the code to confirm the test actually guards it.

Step 1 — Write the function

Create pricing.py:

def final_price(base: float, discount_percent: int) -> float:
    if discount_percent < 0 or discount_percent > 100:
        raise ValueError("discount must be between 0 and 100")
    return round(base * (1 - discount_percent / 100), 2)

Step 2 — Write the test

Create test_pricing.py:

from pricing import final_price
import pytest

def test_no_discount():
    assert final_price(100.0, 0) == 100.0

def test_ten_percent_discount():
    assert final_price(100.0, 10) == 90.0

def test_invalid_discount_raises():
    with pytest.raises(ValueError):
        final_price(100.0, 150)

Each test_ function asserts one expected behavior.

Step 3 — Run the tests

pytest

How to verify it worked: pytest reports 3 passed in green.

Step 4 — Confirm the test actually guards

Temporarily change the discount math in pricing.py (for example, remove the division), run pytest again, and watch it fail. Then revert. How to verify it worked: the test fails when the code is wrong and passes when it’s right — a test that can’t fail guards nothing.

Step 5 — Run it in CI

Add pytest to your GitHub Actions pipeline so the test runs on every change. A test that only runs on your machine is a test that will be forgotten.

Where this bites vibecoders

This is a genuine first-principles gap: people who’ve only ever directed an AI assistant have often never written a test by hand, so they don’t know what “the tests pass” actually means or trust. Writing one test by hand — even one — demystifies the whole loop and makes the assistant’s generated tests legible instead of magical.

Where AI coding assistants get this wrong

  • Generating tests that assert the wrong thing or nothing meaningful.
  • Writing tests after the code that merely echo the implementation.
  • Skipping the “watch it fail” step, so the test is never proven to work.
  • Producing brittle tests that depend on shared state or real services.

Checklist

  • Test one behavior per test function.
  • Assert a specific, meaningful expectation.
  • Watch the test fail once before trusting it.
  • Keep tests fast and independent (no network, no shared state).
  • Run tests in CI on every change.

FAQ

What is pytest?

pytest is Python’s most popular testing framework. It discovers functions and files that match test_* patterns, runs them, and reports pass/fail with helpful output. Its raises helper lets you assert that code raises an exception.

What makes a good unit test?

It’s fast, independent (no shared state or network), deterministic (same result every run), and asserts one clear behavior. A good test reads like a sentence about the code: “a 10% discount on 100 yields 90.”

What is the difference between a unit test and an integration test?

A unit test checks one function in isolation; an integration test checks that multiple pieces work together (like a function and a real database). See Unit vs Integration vs End-to-End Tests.

Sources

Share: