When there are a lot of tests and test files, new questions arise:
- How to group the tests?
- How to run all the tests in one directory?
- How many tests should be there?
- How long should the tests be?
- Can we run the tests in parallel?
Test frameworks solve these issues. They help organize the structure of tests and give many handy things, such as convenient output. We'll get acquainted with most of these features later in the course.
The Pytest framework is popular in the Python world, and we'll focus on it in this lesson.
What is Pytest
Python is one of the few languages whose standard library already includes the latest framework — it is called unittest. It would be logical to look at it here, but it is deeply tied to classes you may not know. Therefore, we're looking at Pytest, which is still more popular than the embedded framework.
Next, we'll create a project from scratch and add tests.
The setup of Pytest
Create a directory somewhere on your computer with the name hexlet_pytest. Go into it and run the following commands:
# Installing Poetry via the link: https://python-poetry.org/docs/#installation
poetry new . # Creating the base structure
poetry install # Installing dependencies
The poetry new
command creates a dummy Python package and adds a directory for future tests. Install Pytest in the dev group using the poetry add-G dev pytest
command. Check that everything is working correctly:
poetry run pytest
# We see a sample output
platform darwin -- Python 3.8.2, pytest-5.4.3, py-1.10.0, pluggy-0.13.1
rootdir: /private/tmp/hexlet_pytest
collected 0 items
======= no tests ran in 0.01s =======
Now, let us add some source code. Create a file hexlet_pytest/example.py with this as the contents:
# This function reverses the given string
def reverse(string):
return string[::-1]
Pytest expects the tests to be in the tests directory at the project root. You can create any structure inside this directory — Pytest will find all the tests there. The naming of test files should be as follows: test_<name>.py. As a rule, <name> corresponds to the name of the tested file.
Let us write our first test. Create a file called tests/test_example.py with the following content:
from hexlet_pytest.example import reverse
def test_reverse():
assert reverse('Hexlet') == 'telxeH'
def test_reverse_for_empty_string():
assert reverse('') == ''
We will take apart the structure of this file later, but let us try to run a test for execution for now:
poetry run pytest
platform darwin -- Python 3.8.2, pytest-5.4.3, py-1.10.0, pluggy-0.13.1
rootdir: /private/tmp/hexlet-pytest
collected 2 items
tests/test_example.py .. [100%]
# We can execute one test like this:
# poetry run pytest tests/test_example.py
https://replit.com/@hexlet/python-testing-pytest
The structure of Pytest
Let us take another look at the test file:
from hexlet_pytest.example import reverse
def test_reverse():
assert reverse('Hexlet') == 'telxeH'
def test_reverse_for_empty_string():
assert reverse('') == ''
Each test inside the file is a function starting with the prefix test_. You can do any number of test functions because everything already depends on the complexity of the tested code. We perform checks using the assert
statement inside the functions.
The assert
instruction works differently in Pytest Despite the similarity with the built-in instructions in Python. Try to make an error in the original function and repeat the tests:
def test_reverse():
> assert reverse('Hexlet') == 'telxeH'
E AssertionError: assert 'Hexlet' == 'telxeH'
E - telxeH
E + Hexlet
tests/test_example.py:4: AssertionError
The output of Pytest contains not only the original statement but also the result of the function call:
- What came out is marked with a plus
- What we expected is marked with a minus
This output makes it much easier to find and fix the error.
There is one peculiarity in the work of Pytest. If you need to print something to the screen, then Pytest will not output anything. By default, it intercepts and suppresses all output. You can turn off this behavior using the -s
flag:
poetry run pytest -s
# Now, you can see everything in the output using `print`
Recommended materials
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.