How To Run A Single Test In Pytest (Using CLI And Markers)

You’ve written code and Unit tests, and want to make sure it works. You simply run the pytest command in your terminal to run them the tests. Boom! some tests fail.

How do you debug it?

To debug, it’s sometimes helpful to run one test, run tests in a specific module or class, or run tests based on a marker.

But how do you run just a single test?

Infact it’s simple and elegant to run any one test in Pytest.

In this article, we’ll learn how to use Pytest to run single tests, control what tests are run, and how to skip tests.

We will also learn about Pytest markers and how to leverage them to categorize or group tests.

Skipping tests can be useful if you’re working on a new feature and don’t want to run the tests for that feature yet.

Or, you may just not need to run all of the tests at a particular time.

Whatever your use case it, it’s good to know how to control what tests you run using Pytest commands from the terminal.

Let’s learn how to do this.

Objectives

After reading this article, you should be able to:

  • Understand how to run basic pytest tests.
  • Control what test to run.
  • Skip tests if needed.
  • Use markers to categorize tests and run specific groups of tests.

Project Set Up

The project has the following structure

Repo structure

Getting Started

To get started, clone the repo here, or you can create your own repo by creating a folder and running git init to initialise it.

Prerequisites

To follow this guide, you should have:

  • Python 3.9 or higher.

  • An elementary grasp of pytest.

  • Understanding of terminal commands.

Create a virtual environment and install the requirements (packages) using

1
pip  install  -r  requirements.txt

Source Code

To better understand running individual tests, we’ll set up a simple project structure. This project has simple functions that perform basic arithmetic operations. We’ll use this project to demonstrate how to run tests in different ways.

Math Operations

In this scenario, we will use simple math operations to demonstrate how to run tests in different ways.

Here are the main code for the project:

operations/core.py

1
2
3
4
5
6
7
8
import pytest

def add_numbers(a: int, b: int) -> int:
return a + b


def multiply_numbers(a: int, b: int) -> int:
return a * b

Tests

The tests are stored in a separate files, typically in a directory named tests. Pytest will automatically discover these tests due to the test_ prefix in the filename and function names.

tests/unit/test_functions.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

from operations.core import add_numbers, multiply_numbers
import pytest

def test_add_positive_numbers():
assert add_numbers(1, 2) == 3

@pytest.mark.end_to_end
def test_add_negative_numbers():
assert add_numbers(-1, -2) == -3

@pytest.mark.skip
def test_add_numbers_zero():
assert add_numbers(0, 0) == 0

class TestsUnit:
@pytest.mark.unit
def test_multiply_numbers(self):
assert multiply_numbers(2, 3) == 6

@pytest.mark.unit
def test_multiply_numbers_zero(self):
assert multiply_numbers(0, 0) == 0


We’ll explain what the various markers @pytest.mark... mean shortly.

Pytest Run Single Test - All Tests

To run all the tests from the root directory, you can use the following command:

1
pytest

The following output will be displayed:

Output of core.py

You can add the -v flag to get more verbose output:

1
pytest -v
Output of core.py

You can enable live console logging using the pytest -s command too. Our article on Pytest Logging covers how to write Pytest logs to console and files easily and even control the log level.

Run Tests in a Module

To run all tests in a specific file (module), use the following command:

1
pytest tests/unit/test_functions.py

The following output will be displayed:

Output of core.py

This allows you to run tests in a specific module, which can be useful when you’re working on a specific module and want to run only the tests for that module.

Run Tests in a Directory

Perhaps you may decide to split your tests by unit, integration, end-to-end, performance, regression and so on.

If you need an overview of the various types of testing for your Python applications, this article on the types of software testing is a good introduction.

In these cases it’s helpful to run tests within a specific directory, and you can use:

1
pytest tests/unit

This will find and run all tests in the unit directory. Similarly you can have directories containing integration, regression or performance tests.

Output of core.py

Run Tests by Node IDs

To run a specific test, you can use the test’s node ID, which is essentially its path in the syntax filename.py::test_function_name.

For example, to run the test_add_negative_numbers function in the test_functions.py file, you can use the following command:

1
pytest tests/unit/test_functions.py::test_add_negative_numbers

This runs the test_add_negative_numbers test in the test_functions.py file.

The following output will be displayed:

Output of core.py

These commands control what tests to run, allowing you to focus on specific areas of your code, which can be particularly useful during development and debugging.

You can find the node ID by running the tests with the -v flag.

Run Tests of a Specific Class

You can also run all tests in a specific class. To do this, you use the :: operator followed by the class name.

For example, to run all tests in the UnitTests class, you can use the following command:

1
pytest tests/unit/test_functions.py::TestsUnit

The following output will be displayed:

Output of core.py

Run Tests by Marker Expressions:

Markers are a powerful tool that can be used to control the execution of your tests.

By using markers, you can run specific groups of tests, exclude tests, and prioritize tests. This can help you to write better tests and to get more value from your test suite.

We’ve covered several kinds of markers in the articles on Pytest Timeout, Pytest Skip Tests and Pytest Asyncio.

In Pytest, you can assign markers to your test functions using the @pytest.mark decorator. You can then use these markers to run specific tests.

This is especially useful when you have different types of tests, such as fast and slow tests, and you want to run them selectively.

To run tests based on marker expressions, you use the -m flag followed by the marker name.

For example in the code we have following functions with markers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@pytest.mark.end_to_end
def test_add_negative_numbers():
assert add_numbers(-1, -2) == -3

@pytest.mark.skip
def test_add_numbers_zero():
assert add_numbers(0, 0) == 0

@pytest.mark.unit
def test_multiply_numbers():
assert multiply_numbers(2, 3) == 6


@pytest.mark.unit
def test_multiply_numbers_zero():
assert multiply_numbers(0, 0) == 0

You can group tests by their type, such as unit tests, integration tests, or end-to-end tests. In the above code, we have marked the tests with the following markers: unit, end_to_end, and skip.

I recommend defining your markers in pytest.ini to avoid the annoying errors in the terminal.

if you’re unfamiliar with using Pytest ini to define your Pytest config, we’ve covered that in depth.

Markers can be easily defined like this in your pytest.ini file:

1
2
3
4
5
[pytest]
markers =
unit : unit tests
end_to_end : end to end tests
skip : slow tests

To run all tests with the unit marker, you can use the following command:

1
pytest -m unit

The following will be the output.

Output of core.py

If You Want to Skip a Test

There may be situations where you want to skip a particular test.

Maybe the test is for a feature that’s not ready yet, or you’re dealing with a known bug that you don’t want to test at the moment. In pytest, skipping a test is simple and can be done using a decorator.

Here’s how it is used in our example:

1
2
3
@pytest.mark.skip
def test_add_numbers_zero():
assert add_numbers(0, 0) == 0

When pytest runs, it will see the @pytest.mark.skip line and know that it should skip this test.

It’s good practice to add a reason for skipping the test like this, allowig colleagues and other developers to understand intention and safely execute the test suite.

1
2
import pytest  
@pytest.mark.skip(reason="Skipping this test for now because of XYZ reason.")

When you run the tests, pytest will show that this test has been skipped and include the reason why.

Output of skip.py

You can find more information on intentionally failing or skipping tests in our article on Pytest Skip Test and XFail.

Conclusion

In this article, we learned how to control what tests are run using the correct pytest CLI commands. We also learned about markers and how they can be used to categorize or group tests.

Here are some of the key takeaways from this article:

  • You can use Pytest to run all tests in a project, or you can run specific tests, run tests in a specific module, or run tests based on a marker.
  • You can skip tests using the @pytest.mark.skip decorator (don’t forget to add a reason for skipping the test! )
  • You can use markers to categorize tests and run specific groups of tests.

If you have ideas for improvement or like for me to cover anything specific, please send me a message via Twitter, GitHub or Email.

Till the next time… Cheers!

Additional Reading

To learn more about Pytest, feel free to bing-read some of our other articles