In this guide you will run how to execute tests with pytest, this assumes that you already have Python and pytest installed and you have the basic knowledge of working with your computer's commandline interface. If not, you can start here.

Running tests with pytest normally involves invoking pytest commands from the command line. The various way how we can invoke the pytest command are highlighted below:

  • Without arguments
  • With file arguments
  • With directory arguments.

Pytest without arguments

If we run the pytest command without any arguments, pytest will recursively traverse the current directory and its sub-directories looking for all available tests files, it will then execute the found test codes. This way you just type 'pytest' in the command interface from the directory where the tests exist and then press enter.

pytest

All tests in the directory where you run the above command (including sub-directories)  will be automatically discovered and executed.

Consider if we have a directory called 'app' with two test files test_1.py and test_2.py

app
├─ test_1.py
└─ test_2.py

Let us put some simple test functions in the two test files.

#test_1.py

def test_add():
   a = 2
   b = 4
   assert a + b == 8

def test_sub():
   a = 2
   b = 4
   assert a - b == 2  #fails

def test_div():
   a =  2
   b = 4
   assert a / b == 0.5
#test_2.py

def testsquare():
   num = 3
   assert num * num == 9

def testPower():
   num = 5
   assert 5 ** 3 == 125

If you now run the pytest command from the app directory, you will get the following output. 

collected 5 items

test_1.py .F.                                                                                                    [ 60%]
test_2.py ..                                                                                                     [100%]

====================================================== FAILURES =======================================================
______________________________________________________ test_sub _______________________________________________________

    def test_sub():
       a = 2
       b = 4
>      assert a - b == 2  #fails
E      assert (2 - 4) == 2

test_1.py:11: AssertionError
=============================================== short test summary info ===============================================
FAILED test_1.py::test_sub - assert (2 - 4) == 2
============================================= 1 failed, 4 passed in 0.17s =============================================

As shown above, the tests are automatically retrieved and executed. From the test report, we can see that 4 tests passed and 1 failed as was expected.

It is very important to not the structure of the test files. Pytest will only consider files with the following format.

  1. test_*.py
  2. *_test.py 

If you are intending your test files to be found automatically without having to  explicitly specify them, your files should follow the two standard formats shown above. For example, this means that a file called "test1.py" will not be considered as a test file  because it does not follow either of the two formats.

If you want to make the test report more detailed, you can increase the verbosity by adding -v in the pytest command, as shown below.

pytest -v

Pytest with file arguments

In some cases, you may want to run specific test file(s). The  pytest command allows you to specify the paths of the specific file you want to be executed. This way, only the specified test files will get executed, the rest will not.

the syntax is as shown below:

pytest path/to/test_abc.py

For example, to execute only test_2.py,  we can run the following command in the "app" directory.

pytest test_2.py

If you run the above command directory, only the tests in test_2.py gets executed, the output will be as shown below:

collected 2 items

test_2.py ..                                                                                                     [100%]

================================================== 2 passed in 0.03s ==================================================

As you can see above, only the 2 tests in test_2.py get executed.

Note that the path name is relative to the current commandline location , for example, if the current location was in the parent directory of the "app" directory we would have used 'app/test_2.py' rather than just 'test_2.py'

You can pass as many space-separated filenames as necessary.

pytest path/test_a.py path/test_b.py path/test_c.py ...

The test  files will be executed in the order they are listed in the command.

For example to run both test files in our "app" directory, we can run the following command.

pytest test_2.py test1.py

The output after running the above command will be as shown below:

collected 5 items

test_2.py ..                                                                                                     [ 40%]
test_1.py .F.                                                                                                    [100%]

====================================================== FAILURES =======================================================
______________________________________________________ test_sub _______________________________________________________

    def test_sub():
       a = 2
       b = 4
>      assert a - b == 2  #fails
E      assert (2 - 4) == 2

test_1.py:11: AssertionError
=============================================== short test summary info ===============================================
FAILED test_1.py::test_sub - assert (2 - 4) == 2
============================================= 1 failed, 4 passed in 0.17s =============================================

With this approach, it is not necessary for the test files to have the format that we had talked about in the previous section. This means that you can name the test files to any valid name, however, it is wise to stick to pytest standard naming convention.

Pytest with Directory arguments

In some cases, we may want to execute all the test files inside a specific directory. We can achieve this by specifying the path to that directory in the pytest command.

pytest path/to/test_dir/ path/to/test_dir2/ ...

For example we can run the following command in the parent directory of the our 'app' directory,

​pytest app/

If you run the above command both test_1.py and test_2.py will be discovered and their tests executed.

collected 5 items

app\test_1.py .F.                                                                                                [ 60%]
app\test_2.py ..                                                                                                 [100%]

====================================================== FAILURES =======================================================
______________________________________________________ test_sub _______________________________________________________

    def test_sub():
       a = 2
       b = 4
>      assert a - b == 2  #fails
E      assert (2 - 4) == 2

app\test_1.py:11: AssertionError
=============================================== short test summary info ===============================================
FAILED app/test_1.py::test_sub - assert (2 - 4) == 2
============================================= 1 failed, 4 passed in 0.60s =============================================

Running only one test

In some cases, you may want to just run a single test function in a given test file. For example, we may want to only run the test_sub() function in the test_1.py file.

To achieve this, we include the name of the target function in the pytest command with the following format.

pytest path/to/test_file.py::test_function

For example:

pytest  app/test_1.py::test_sub

The output will be as shown below:

collected 1 item

app\test_1.py F                                                                                                  [100%]

====================================================== FAILURES =======================================================
______________________________________________________ test_sub _______________________________________________________

    def test_sub():
       a = 2
       b = 4
>      assert a - b == 2  #fails
E      assert (2 - 4) == 2

app\test_1.py:11: AssertionError
=============================================== short test summary info ===============================================
FAILED app/test_1.py::test_sub - assert (2 - 4) == 2
================================================== 1 failed in 0.18s ==================================================

As you can see from the above output, only the single specified function was collected and executed.