How to Use Pytest

What you’ll build or solve

You’ll write and run tests with Pytest so you can catch bugs early and refactor with more confidence.

When this approach works best

Pytest works best when you want to:

  • Add fast unit tests for functions, like parsing input or calculating values.
  • Prevent regressions after refactoring, so old behavior stays consistent.
  • Check edge cases, like empty input, invalid data, or boundary values.

This is a bad idea when you are writing a throwaway script you will never run again. For anything you plan to maintain, tests pay off.

Prerequisites

  • Python 3 installed
  • Pytest installed in the environment you use for the project

If you need to install it:

python-m pip install pytest

Step-by-step instructions

1) Create test files Pytest can discover

Pytest looks for files named test_*.py or *_test.py. Put your tests in one of those files and name test functions with test_.

# test_math_utils.py

defadd(a,b):
returna+b

deftest_adds_two_numbers():
assertadd(2,3)==5

What to look for: If your file or function name does not match these patterns, Pytest will skip it.


2) Run your tests from the command line

From the folder that contains your test file, run:

pytest

For a more detailed list of tests:

pytest-v

What to look for: If Pytest says “collected 0 items,” your test file or test function names do not match discovery rules.


3) Write assertions that check behavior

Pytest uses normal Python assert statements. Keep them focused on one behavior at a time.

defformat_username(name):
returnname.strip().lower().replace(" ","_")

deftest_formats_username():
assertformat_username(" Noor Ali ")=="noor_ali"

If you want to test errors, use pytest.raises.

importpytest

defparse_age(value):
value=value.strip()
ifnotvalue.isdigit():
raiseValueError("age must be a number")
returnint(value)

deftest_parse_age_invalid():
withpytest.raises(ValueError):
parse_age("thirty")

Examples you can copy

Example 1: Run one test file or one test function

pytest test_math_utils.py
pytest test_math_utils.py::test_adds_two_numbers

Example 2: Test a function that returns a dict

defbuild_profile(name,city):
return {"name":name,"city":city}

deftest_build_profile():
assertbuild_profile("Amina","Boston")== {
"name":"Amina",
"city":"Boston",
    }

Example 3: Test string output with a clear diff

defgreet(name):
returnf"Hello,{name}"

deftest_greet():
assertgreet("Luka")=="Hello, Luka"

If this fails, Pytest shows a helpful diff between expected and actual output.


Example 4: Use a temporary folder for file tests

Pytest provides a built-in tmp_path fixture.

deftest_write_temp_file(tmp_path):
p=tmp_path/"note.txt"
p.write_text("hi",encoding="utf-8")

assertp.read_text(encoding="utf-8")=="hi"

Example 5: Mark and run a subset of tests

importpytest

@pytest.mark.slow
deftest_slow_operation():
assertsum(range(10_000))>0

Run only that group:

pytest-m slow

Example 6: Share setup with fixtures

importpytest

@pytest.fixture
defsample_users():
return ["Amina","Luka","Noor"]

deftest_has_three_users(sample_users):
assertlen(sample_users)==3

Fixtures help you avoid repeating setup code.


Example 7: Test multiple cases with parametrize

importpytest

defis_even(n):
returnn%2==0

@pytest.mark.parametrize("n,expected", [
    (0,True),
    (1,False),
    (2,True),
    (11,False),
])
deftest_is_even(n,expected):
assertis_even(n)==expected

parametrize lets you test many inputs with one test function.


Common mistakes and how to fix them

Mistake 1: Pytest collects 0 tests

What you might do

  • Name a file tests.py
  • Name a test function adds_two_numbers()

Why it breaks

Pytest discovery relies on:

  • File: test_*.py or _test.py
  • Function: test_*

Corrected approach

# test_numbers.py

deftest_adds_two_numbers():
assert2+3==5

Mistake 2: Using print() instead of assertions

What you might do

deftest_total():
total=2+2
print(total)

Why it breaks

A test can pass without checking anything.

Corrected approach

deftest_total():
assert2+2==4

Troubleshooting

If you see pytest: command not found, run it through Python:

python-m pytest

If you see ModuleNotFoundError for your own code, run Pytest from the project root folder, where your package or module can be imported.

If you see “collected 0 items,” check the naming:

  • File: test_*.py or _test.py
  • Function: test_*

If tests pass locally but fail elsewhere, compare Python versions:

python--version

Then confirm you installed dependencies in the environment that runs the tests.

If you want to focus on one failure, run a single test with verbose output:

pytest path/to/test_file.py::test_name-v

Quick recap

  • Name files test_*.py and functions test_* so Pytest finds them.
  • Run tests with pytest or python -m pytest.
  • Use plain assert to check behavior, and pytest.raises for errors.
  • Use fixtures and parametrize when you want a cleaner setup or more coverage.