PyTest
| Introduction | |
| Example | |
| Structure of the project | |
| Testing arguments for type | |
| Launching Unittest Tests | |
| Add PyTest to PyCharm | |
| Similar articles |
Introduction
Pytest supports tests created with
unittest
.
The main advantage of Pytest is the peculiarities of writing TestCase.
TestCase in pytest is a series of functions in a Python file.
It starts with the name test .
Pytest has other distinctive features:
- support for the built-in assert operator (no need to use special methods of self.assert);
- Filtration support;
- the ability to restart, starting with the last failed test;
- An ecosystem of hundreds of plugins that extend functionality.
Writing the TestSum test in pytest looks like this:
def test_sum():
assert sum([1, 2, 3]) == 6, "Should be 6"
def test_sum_tuple():
assert sum((1, 2, 2)) == 6, "Should be 6"
It removes the TestCase base class and any use of classes in principle, as well as the entry point from the command line. As usual, more information is available on the Pytest website.
Example without IDE
The simplest example in the console
Linux
You need to prepare the environment and create two files - with the code and the test for this code.
The file with the code can be called whatever you want - preferably with a small letter and a name that does not match the reserved ones.
The file with the test is usually also called but with the prefix test or less often the postfix test.
mkdir /home/$(whoami)/python/pytest/qa
cd /home/$(whoami)/python/pytest/qa
python -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
python -m pip install pytest
touch psum.py test_psum.py
In the file psum.py write a simple function, such as addition
def add(x, y): return x + y
In the file. test_psum.py It will be a test for this function.
from psum import add def test_psum(): assert add(2, 3) == 5, "Should be 5"
To start the test you need to perform
pytest test_psum.py
================================================= test session starts ================================================== platform linux -- Python 3.9.5, pytest-7.0.1, pluggy-1.0.0 rootdir: /home/andrei/python/pytest/qa collected 1 item test_psum.py . [100%] ================================================== 1 passed in 0.01s ===================================================
If the function returns a different result than expected, for example, in case of an error in the test itself.
assert add(2, 3) == 999, "Should be 999"
pytest test_psum.py
================================================= test session starts ================================================== platform linux -- Python 3.9.5, pytest-7.0.1, pluggy-1.0.0 rootdir: /home/andrei/python/pytest/qa collected 1 item test_psum.py F [100%] ======================================================= FAILURES ======================================================= ______________________________________________________ test_psum _______________________________________________________ def test_psum(): > assert add(2, 3) == 999, "Should be 999" E AssertionError: Should be 999 E assert 5 == 999 E + where 5 = add(2, 3) test_psum.py:4: AssertionError =============================================== short test summary info ================================================ FAILED test_psum.py::test_psum - AssertionError: Should be 999 ================================================== 1 failed in 0.02s ===================================================
Project structure with PyTest tests
Once the project outgrows the microscopic size, keep the tests in the same directory with the code. becomes uncomfortable
Suppose the project code is in the directory app You can move the test file. test_psum.py subdirectory tests
app ├── psum.py ├── __pycache__ │ ├── psum.cpython-39.pyc │ └── test_psum.cpython-39-pytest-7.0.1.pyc ├── tests │ ├── __pycache__ │ └── test_psum.py └── venv ├── bin ├── include ├── lib ├── lib64 -> lib └── pyvenv.cfg
If you run the test from the app directory, pytest will understand how to import. psum
python -m pytest tests/test_psum.py
If you run the same test directly from the test directory, an error will appear. ImportError while importing test module
Testing arguments for type
PyTest application demonstrations often begin with addition or multiplication functions.
For example,
# Code def prod(a, b): return a * b
# Test from prod import prod def test_prod(): res = prod(3, 4) assert res == 12
python -m pytest tests/test_prod.py
This function involves the use of numbers. But there's no validation.
With help.
We add validation and write a test.
# prod.py def prod(a, b): if not all( map(lambda p: isinstance(p, (int, float)), (a, b)) ): raise TypeError("Not valid argument data type") print("prod.py: Valid arguments") return a * b
# test_prod.py import pytest from prod import prod def test_prod(): res = prod(3, 4) assert res == 12 def test_arguments(): try: Knowingly incorrect data type must be caught # "" is a string and should not be accepted res = prod("", 4) except TypeError as err: # if TypeError is caught pass else: print("test_prod.py: Invalid argument is not caught") pytest.fail() # assert False
Instead of pytest.fail(), you can use assert False, and import pytest is optional.
python -m pytest -v tests/test_prod.py
================================ test session starts ================================ platform linux -- Python 3.9.5, pytest-7.0.1, pluggy-1.0.0 -- /home/andrei/python/pytest/otus/venv/bin/python cachedir: .pytest_cache rootdir: /home/andrei/python/pytest/app collected 2 items tests/test_prod.py::test_prod PASSED [ 50%] tests/test_prod.py::test_arguments PASSED [100%] ================================= 2 passed in 0.01s =================================
If the test breaks, PyTest will give the following result.
================================ test session starts ================================ platform linux -- Python 3.9.5, pytest-7.0.1, pluggy-1.0.0 -- /home/andrei/python/pytest/otus/venv/bin/python cachedir: .pytest_cache rootdir: /home/andrei/python/pytest/app collected 2 items tests/test_prod.py::test_prod PASSED [ 50%] tests/test_prod.py::test_arguments FAILED [100%] ===================================== FAILURES ====================================== __________________________________ test_arguments ___________________________________ def test_arguments(): try: # "" is a string and should not be accepted res = prod(3, 4) except TypeError as err: # if TypeError is caught pass else: print("test_prod.py: Invalid argument is not caught") > pytest.fail() E Failed tests/test_prod.py:19: Failed ------------------------------- Captured stdout call -------------------------------- prod.py: Valid arguments test_prod.py: Invalid argument is not caught ============================== short test summary info ============================== FAILED tests/test_prod.py::test_arguments - Failed ============================ 1 failed, 1 passed in 0.02s ============================
unittest from PyTest
If there are already tests on the project
unittest
PyTest will understand the syntax unittest
Let's see.
test the solution of the quadratic equation on unittest
If you run the same tests using PyTest
python -m pytest -v tests/test_quadratic.py
================================================== test session starts =================================================== platform linux -- Python 3.9.5, pytest-7.0.1, pluggy-1.0.0 -- /home/andrei/python/unittest/app/venv/bin/python cachedir: .pytest_cache rootdir: /home/andrei/python/unittest/app collected 5 items tests/test_quadratic.py::TestQuadratic::test_raises_type_error PASSED [ 20%] tests/test_quadratic.py::TestQuadratic::test_result_is_tuple PASSED [ 40%] tests/test_quadratic.py::TestQuadratic::test_single_root PASSED [ 60%] tests/test_quadratic.py::TestQuadratic::test_two_roots PASSED [ 80%] tests/test_quadratic.py::TestQuadratic::test_zero_a_and_b PASSED [100%] =================================================== 5 passed in 0.01s ====================================================
Add PyTest to Pycharm
To add PyTest to PyCharm Use the following instructions
Settings (Ctrl + Alt + S) → Tools → Python Integrated Tools → Default test runner:
Choose. pytest. If it has not yet been added, a warning will appear. and the Fix button.
You need to press the Fix button.
A message will appear at the bottom of the main settings screen
Installing package 'pytest'
Wait until it is replaced by a message about a successful installation and the warning disappears from the screen.
Article author: Andrei Olegovich
| Testing | |
| Python |