GGistDev

Testing in Python

Write automated tests to validate behavior and prevent regressions. Popular tools: unittest (stdlib) and pytest.

Project structure

Keep tests close to code or in a top-level tests/ package.

src/
  app/
    core.py
tests/
  test_core.py

unittest (stdlib)

unittest provides xUnit-style test cases and assertions.

import unittest
from app.core import add

class TestCore(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)

if __name__ == "__main__":
    unittest.main()

Run with python -m unittest -v.

pytest (concise)

pytest discovers tests by naming conventions and simplifies assertions.

# tests/test_core.py
from app.core import add

def test_add():
    assert add(2, 3) == 5

Run with pytest -q.

Fixtures

Fixtures set up reusable state.

import pytest

@pytest.fixture
def tmp_user():
    return {"name": "Ada"}

def test_user(tmp_user):
    assert tmp_user["name"] == "Ada"

Parametrization

Test many inputs succinctly.

import pytest

@pytest.mark.parametrize("a,b,sum_", [(1,2,3), (0,0,0), (-1,1,0)])
def test_add(a, b, sum_):
    assert a + b == sum_

Mocking

Isolate units with doubles.

from unittest.mock import patch

with patch("app.core.now", return_value=0):
    ...

Coverage

Measure coverage with coverage.py.

coverage run -m pytest
coverage html

Best practices

  • Test behavior, not implementation details
  • Keep tests independent and deterministic
  • Use fixtures/factories to reduce duplication
  • Run tests in CI; enforce coverage thresholds sensibly

Summary

  • unittest and pytest are the main tools
  • Use fixtures, parametrization, and mocking to write clear, robust tests