Pytest in Python: Complete Beginner’s Guide

Published on: July 10, 2026
Reading time: 10 minutes
Ilustração minimalista de testes automatizados com Pytest em Python

Manual testing works well when a Python program is small. You run the file, enter a few values, and check the result yourself. As the project grows, however, repeating the same checks after every change becomes slow and easy to forget. This is where Pytest in Python becomes especially useful.

Pytest lets you write small automated tests that confirm whether your functions still behave as expected. When something breaks, it reports which test failed, where the failure happened, and which values were compared.

In this beginner-friendly guide, you will learn how to install Pytest, write your first test, understand assert, test expected exceptions, organize test files, and use the most helpful commands. No previous experience with automated testing is required.

What Is Pytest?

Pytest is a testing framework for Python. It discovers and runs test functions, then gives you a clear report showing which tests passed and which ones failed.

An automated test is simply code that runs another part of your program and compares the actual result with the expected result. Suppose you have a function that adds two numbers. You expect add(2, 3) to return 5. Instead of checking that manually after every change, you can write a test that performs the verification in milliseconds.

Pytest is commonly used for unit testing in Python. A unit test usually checks a small piece of a program, such as one function or method. Pytest can also support larger test suites for APIs, databases, command-line tools, and web applications.

One reason beginners like Pytest is its simple syntax. In many cases, you only need a function whose name starts with test_ and an assert statement. You can begin with the basics and add more advanced features later.

Why Should You Learn Pytest?

Automated tests are not limited to large companies or complex software. They are also valuable in personal projects, coding exercises, data scripts, and small automation tools.

Tests help you change code with more confidence. After editing a function, you can run the entire test suite and quickly see whether an existing behavior was accidentally broken.

  • Catch mistakes soon after a code change.
  • Prevent previously fixed bugs from returning.
  • Document how a function is expected to behave.
  • Make refactoring safer.
  • Reduce repetitive manual checks.
  • Improve confidence before releasing a new version.

A passing test suite does not prove that an application has no bugs. It only confirms the behaviors covered by the tests you wrote. Good tests therefore focus on meaningful cases, including normal inputs, edge cases, and invalid values.

What You Need Before Starting

To follow this tutorial, you need Python installed and basic familiarity with running commands in a terminal. It also helps to understand how functions work. If that topic is still new, review this introduction to Python functions.

You can write the examples in any code editor. Visual Studio Code is a practical choice, but the same files will work in PyCharm, IDLE, or another editor.

Create a folder named pytest_project and open it in your editor. Using a virtual environment is strongly recommended because it keeps the project’s dependencies separate from packages installed elsewhere on your computer. This guide to creating a Python virtual environment with venv explains the process in more detail.

How to Install Pytest

Open a terminal inside your project folder and create a virtual environment:

python -m venv .venv

On Windows, activate it with:

.venv\Scripts\activate

On Linux or macOS, use:

source .venv/bin/activate

Now install Pytest:

python -m pip install -U pytest

You will often see pip install pytest in tutorials. Using python -m pip helps ensure that the package is installed for the same Python interpreter used by the project. For more background, see how to install Python packages with pip.

Confirm that the installation worked:

pytest --version

The terminal should display the installed version. The official Pytest getting-started guide uses the same installation and version-checking process. The Python Packaging User Guide provides additional official guidance on virtual environments and package installation.

Create the Code You Want to Test

Inside the project folder, create a file named calculator.py. Add a simple function:

def add(a, b):
    return a + b

The function receives two values and returns their sum. You could open the Python interpreter and try several values manually, but we will create a test file that performs those checks automatically.

Write Your First Pytest Test

Create a second file in the same folder and name it test_calculator.py. The test_ prefix matters because Pytest uses naming conventions to discover test files automatically.

Add the following code:

from calculator import add


def test_add_two_numbers():
    result = add(2, 3)
    assert result == 5

Here is what each part does:

  • from calculator import add imports the function being tested.
  • def test_add_two_numbers() defines a test function.
  • result = add(2, 3) runs the real application code.
  • assert result == 5 checks whether the result matches the expected value.

The test function also starts with test_. Pytest uses this naming pattern to find tests. Descriptive names are better than vague names such as test_1, because they immediately explain which behavior is being checked.

Run Your First Test

In the terminal, make sure you are inside the project folder and that the virtual environment is active. Then run:

pytest

If everything is correct, the output will look similar to this:

collected 1 item
test_calculator.py .                         [100%]
1 passed

The dot means the test passed. The message 1 passed confirms that Pytest found and successfully executed one test.

For more detailed output, use:

pytest -v

The -v option means verbose. It displays the full name of each test. For a shorter report, use:

pytest -q

What Happens When a Test Fails?

One of Pytest’s strongest features is its readable failure report. Temporarily change the expected result to an incorrect value:

def test_add_two_numbers():
    result = add(2, 3)
    assert result == 6

Run pytest again. The test will fail because adding 2 and 3 produces 5, not 6. You will see output similar to:

E       assert 5 == 6
FAILED test_calculator.py::test_add_two_numbers

Pytest shows the actual value, the expected value, the test name, and the line where the comparison failed. This makes it easier to understand the problem than a simple generic error message.

A failed test does not automatically mean Pytest is broken. Usually, one of these situations is responsible:

  • The application code contains a bug.
  • The expected value in the test is incorrect.
  • The test does not accurately represent the intended rule.

After reviewing the failure, change the expected result back to 5.

Add More Test Cases

A single test rarely covers every useful scenario. Add tests for negative numbers and zero:

from calculator import add


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


def test_add_negative_number():
    assert add(-2, 5) == 3


def test_add_zero():
    assert add(10, 0) == 10

Run pytest -v and Pytest will list all three tests separately. If one scenario fails, you will know exactly which behavior needs attention.

Keep tests focused. A small test that checks one behavior is usually easier to understand and maintain than a large test that performs many unrelated checks.

How to Test Exceptions with pytest.raises()

Not every test expects a function to return a value. Sometimes the correct behavior is to raise an exception. Add this function to calculator.py:

def divide(a, b):
    if b == 0:
        raise ValueError("The divisor cannot be zero")

    return a / b

Now update the test file:

import pytest

from calculator import add, divide


def test_divide_by_zero():
    with pytest.raises(ValueError):
        divide(10, 0)

The with pytest.raises(ValueError) block tells Pytest that the function is expected to raise a ValueError. The test passes when that exception occurs and fails when it does not.

This approach is useful for validation rules, file operations, conversions, and business logic. To understand the underlying exception-handling concepts, review this guide to try and except in Python.

You can also check the exception message:

def test_divide_by_zero_message():
    with pytest.raises(ValueError, match="The divisor cannot be zero"):
        divide(10, 0)

How to Organize Test Files

For a very small project, source files and tests can stay in the same folder. As the project grows, a separate tests directory creates a clearer structure:

pytest_project/
├── calculator.py
└── tests/
    └── test_calculator.py

Run Pytest from the pytest_project directory. By default, it searches the current folder and subfolders for files named like test_*.py or *_test.py.

Useful conventions include:

  • Keep tests in a dedicated tests folder.
  • Start test filenames with test_.
  • Start test function names with test_.
  • Use names that describe the scenario.
  • Keep application code separate from test code.

Consistent formatting also makes tests easier to scan. The overview of PEP 8 style guidelines covers practical conventions for readable Python code.

Useful Pytest Commands for Beginners

You do not need to memorize dozens of options. The following commands cover many common beginner workflows.

Run All Tests

pytest

Show Test Names

pytest -v

Run One Test File

pytest tests/test_calculator.py

Run Tests Whose Names Match a Word

pytest -k add

This command runs tests with add in their names.

Stop After the First Failure

pytest --maxfail=1

Run Only Tests That Failed Last Time

pytest --lf

The --lf option means “last failed.” It is helpful when you are working on a specific problem and do not need to rerun every passing test.

Common Pytest Problems and Fixes

The pytest Command Is Not Recognized

Check that the virtual environment is active and that installation completed successfully. You can also run:

python -m pytest

This tells Python to load the installed module directly.

Pytest Finds No Tests

Make sure the filename starts with test_ or ends with _test.py. Test functions should also start with test_.

The Application Module Cannot Be Imported

Run the command from the project’s root folder. Check the module name and avoid spaces or hyphens in Python filenames.

Your File Is Named pytest.py

Do not name your own file pytest.py. It can shadow the real Pytest package and cause confusing import errors.

The Test Passes Without Checking Anything

Pytest can run a function whose name starts with test_ even when it contains no assertion. Make sure every test has a clear expectation, such as an assert statement or an expected exception.

The Failure Output Is Difficult to Understand

Run pytest -v and focus on the first failure. If necessary, use breakpoints and learn how to debug Python in VS Code.

Beginner-Friendly Testing Practices

Start with functions that accept inputs and return predictable outputs. These are usually easier to test than code that depends on network requests, files, databases, or user interfaces.

  • Give every test a descriptive name.
  • Test one main behavior per function.
  • Include normal inputs, edge cases, and invalid values.
  • Do not depend on the order in which tests run.
  • Do not make one test depend on another test’s result.
  • Run the suite after changing application code.
  • Keep tests as readable as the code they verify.

A useful pattern for thinking about each test is:

  1. Arrange: prepare the required inputs or state.
  2. Act: call the function being tested.
  3. Assert: compare the result with the expectation.

In the first example, we arranged the values 2 and 3, acted by calling add, and asserted that the result was 5.

What to Learn After This Guide

Once the basics feel comfortable, you can explore features that reduce repetition and support larger projects:

  • Fixtures: prepare reusable data and resources.
  • Parametrization: run one test with several inputs.
  • Mocks: replace external services or dependencies during tests.
  • Coverage: show which lines of code were executed by tests.
  • Continuous integration: run tests automatically when code is pushed.

You do not need to learn all of these topics at once. A small set of clear tests already provides real value and helps you build the habit of checking code continuously.

Conclusion

Pytest in Python provides a straightforward way to begin automated testing. Install the package, create files and functions whose names start with test_, use assert to compare results, and run the suite with the pytest command.

In this tutorial, you tested an addition function, inspected an intentional failure, covered multiple scenarios, and used pytest.raises() to verify an expected exception. You also learned a practical folder structure, useful commands, and common fixes.

As a next exercise, add subtraction, multiplication, and division functions to calculator.py. Write at least two tests for each function. That small project will help you understand the complete workflow before moving on to fixtures, parametrization, and mocks.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Uso da função enumerate em loops Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python enumerate(): Cleaner Loops with Indexes

    Learn Python enumerate() to loop with indexes, choose a custom start value, combine it with zip, process files, and avoid

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Pessoa pensando com um monitor desfocado ao fundo
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python Data Types: int, float, str, list, and dict Explained

    When you start programming in Python, you quickly realize you need to store many kinds of information. Numbers, text, product

    Ler mais

    Tempo de leitura: 12 minutos
    08/07/2026
    Introdução ao módulo sys para iniciantes em Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python sys Module for Beginners

    Learn Python's sys module: check Python version, read command-line args with sys.argv, manage sys.path, use sys.exit(), and measure object size.

    Ler mais

    Tempo de leitura: 3 minutos
    03/06/2026
    Uso do with para abrir arquivos com segurança em Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python with Statement: Safe File Handling

    Learn how Python's with statement safely opens files: automatic close, read/write modes, CSV handling, multiple files, and context manager basics.

    Ler mais

    Tempo de leitura: 3 minutos
    03/06/2026
    Operações matemáticas usando o módulo math em Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python math Module: Mathematical Operations

    Learn Python's math module: sqrt, pow, ceil, floor, trig functions, logarithms, constants like pi and e, and special numeric checks

    Ler mais

    Tempo de leitura: 3 minutos
    03/06/2026
    Uso do módulo time para controlar tempo em scripts Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python time Module for Beginners

    Learn how Python's time module works: Unix timestamp, time.sleep() for pauses, localtime(), strftime() for date formatting, and measure execution time.

    Ler mais

    Tempo de leitura: 3 minutos
    03/06/2026