How to Reduce Pytest Execution Times

How to Reduce Pytest Execution Times

I have to admit, after adding the final test for checking the Nornir course code repo, it felt good. 56 tests in total. Job done! Well, kind of. After performing a final run and feeling smug that I was getting a screen of green passes, it raised the next question:

How can I speed up Pytest to run faster?

As it stood, it took around 2 minutes to run all the tests due to Pytest running them sequentially.

After some quick Googling, I discovered the awesome tool - pytest-xdist. In a nutshell, pytest-xdist is a Pytest plugin that (from the pytest-xdist repo):

extends Pytest with new test execution modes, the most used being distributing tests across multiple CPUs to speed up test execution.

Great! Here's a quick example:

# Install (for pip users, perform a pip install pytest-xdist, instead).
$ poetry add pytest-xdist

# Use -n auto to spawn work processes equal to CPUs and distribute tests across them. 
$ pytest -v tests/ -n auto
...

The result? The testing was reduced from 2mins to ~30 secs!

$ pytest -v tests/ -n auto
========================================================================================================= test session starts =========================================================================================================
platform linux -- Python 3.8.5, pytest-7.1.1, pluggy-1.0.0 -- /home/rick/.cache/pypoetry/virtualenvs/nornir-course-iatnHwlm-py3.8/bin/python
cachedir: .pytest_cache
rootdir: /mnt/c/Users/rick/nornir-course
plugins: forked-1.4.0, xdist-2.5.0
[gw0] linux Python 3.8.5 cwd: /mnt/c/Users/rick/nornir-course
[gw1] linux Python 3.8.5 cwd: /mnt/c/Users/rick/nornir-course
[gw2] linux Python 3.8.5 cwd: /mnt/c/Users/rick/nornir-course
...
[gw0] Python 3.8.5 (default, Jan 27 2021, 15:41:15)  -- [GCC 9.3.0]
[gw1] Python 3.8.5 (default, Jan 27 2021, 15:41:15)  -- [GCC 9.3.0]
[gw2] Python 3.8.5 (default, Jan 27 2021, 15:41:15)  -- [GCC 9.3.0]
[gw3] Python 3.8.5 (default, Jan 27 2021, 15:41:15)  -- [GCC 9.3.0]
...  
gw0 [56] / gw1 [56] / gw2 [56] / gw3 [56] / gw4 [56] / gw5 [56] / gw6 [56] / gw7 [56]
scheduling tests via LoadScheduling

tests/test_003_inventory.py::test_nr_print_inventory_dynamic 
tests/test_003_inventory.py::test_nr_print_inventory_static 
tests/test_003_inventory.py::test_nr_cred_inject 
tests/test_002_config.py::test_inspect_config 
tests/test_001_fundamentals.py::test_run_first_test 
tests/test_002_config.py::test_set_config_dict 
tests/test_003_inventory.py::test_nr_inspect_inventory 
tests/test_002_config.py::test_set_config_yaml 
[gw1] [  1%] PASSED tests/test_002_config.py::test_set_config_yaml 
[gw2] [  3%] PASSED tests/test_002_config.py::test_set_config_dict 
[gw6] [  5%] PASSED tests/test_003_inventory.py::test_nr_cred_inject 
[gw3] [  7%] PASSED tests/test_002_config.py::test_inspect_config 
tests/test_004_tasks.py::test_changed 
tests/test_004_tasks.py::test_creating_a_task 
tests/test_003_inventory.py::test_f_object_filtering 
tests/test_004_tasks.py::test_running_a_task 
[gw4] [  8%] PASSED tests/test_003_inventory.py::test_nr_print_inventory_static 
tests/test_004_tasks.py::test_grouping_tasks 
[gw7] [ 10%] PASSED tests/test_003_inventory.py::test_nr_inspect_inventory 
tests/test_004_tasks.py::test_failed 
[gw3] [ 12%] PASSED tests/test_004_tasks.py::test_creating_a_task 
[gw6] [ 14%] PASSED tests/test_004_tasks.py::test_changed 
...
tests/test_009_imports.py::test_imports[007_plugins/004_scrapli.py] 
[gw6] [ 94%] PASSED tests/test_009_imports.py::test_imports[007_plugins/002_netmiko.py] 
[gw2] [ 96%] PASSED tests/test_009_imports.py::test_imports[007_plugins/003_napalm.py] 
[gw3] [ 98%] PASSED tests/test_008_processors.py::test_progress_bar 
[gw0] [100%] PASSED tests/test_009_imports.py::test_imports[008_processors/002_progress_bars.py] 

========================================================================================================== warnings summary ===========================================================================================================
...
================================================================================================== 56 passed, 26 warnings in 29.16s ===================================================================================================

Great stuff!

Subscribe to our newsletter and stay updated.

Don't miss anything. Get all the latest posts delivered straight to your inbox.
Great! Check your inbox and click the link to confirm your subscription.
Error! Please enter a valid email address!