I have identified some long running pytest tests with
py.test --durations=10
I would like to instrument one of those tests now with something like line_profiler or cprofile. I really want to get the profile data from the test itself as the pytest setup or tear down could well be part of what is slow.
However given how line_profiler or cprofile is typically involved it isn't clear to me how to make them work with pytest.
Run Multiple Tests From a Specific File and Multiple Files To run all the tests from all the files in the folder and subfolders we need to just run the pytest command. This will run all the filenames starting with test_ and the filenames ending with _test in that folder and subfolders under that folder.
Try this: py. test test_basic.py -k test_first here test_first is a test case present in my test_basic.py file. Use the :: syntax to run a single test in a test file, e.g.: pytest tests/test_models.py::TestMyModel . TestMyModel is a class that contains a subset of tests.
Pytest supports several ways to run and select tests from the command-line. This will run tests which contain names that match the given string expression (case-insensitive), which can include Python operators that use filenames, class names and function names as variables.
The simplest way to skip a test is to mark it with the skip decorator which may be passed an optional reason . It is also possible to skip imperatively during test execution or setup by calling the pytest. skip(reason) function. This is useful when it is not possible to evaluate the skip condition during import time.
Run pytest like this:
python3 -m cProfile -o profile -m pytest
You can even pass in optional arguments:
python3 -m cProfile -o profile -m pytest tests/worker/test_tasks.py -s campaigns
This will create a binary file called profile
in your current directory. This can be analyzed with pstats:
import pstats p = pstats.Stats('profile') p.strip_dirs() p.sort_stats('cumtime') p.print_stats(50)
This will print the 50 lines with the longest cumulative duration.
To get cProfile
and line_profiler
to work with py.test
code, I did two things:
Extended the py.test test code with a call to pytest.main(), which made it executable with the python interpreter as the main driver:
# pytest_test.py: @profile # for line_profiler only def test_example(): x = 3**32 assert x == 1853020188851841 # for profiling with cProfile and line_profiler import pytest pytest.main(__file__)
Now you can run this test without py.test
as the main driver using other tools:
$ kernprof.py -l pytest_test.py $ python -m line_profiler pytest_test.py.lprof
or
$ python -m cProfile pytest_test.py
To profile py.test-specific functions such as pytest_funcarg*()
with line_profiler
I split them in two to avoid confusion between py.test
and line_profiler
:
def pytest_funcarg__foo(request): return foo(request) @profile def foo(request): ...
The same method works for memory_profiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With