I’ve been using pytest for a few months now to help me to test individual functions and algorithms as I develop them. So far I’ve been impressed by how easy it is to setup my tests. Reading some of my previous posts would tell you that I like optimising code for speed (perhaps a little too much for my own good). One particular algorithm was taking several minutes for each test case, so of course I had to fix this.
I used the cProfile module to obtain profiling data, showing how often each function was called, the time spent on statements within that function (excluding calls to other functions), time spent in a function including calls to other functions and the average time per call to each function. Among other things, this helped to evaluate how changes to individual functions actually performed and to guide my optimisation efforts.
Mixing pytest and cProfile is actually quite easy to do. Normally, executing
would run the tests defined in test_X.py. In order to profile these tests using cProfile, two changes are needed. Firstly, the command line changes to
python -m cProfile -o test_X.profile test_X.py
Using -m cProfile executes the cProfile module, while -o test_X.profile causes the profiling data to be stored in the file test_X.profile. Note that the script defining the tests is directly invoked here, instead of using py.test. This requires the following addition at the end of test_X.py to make it invoke pytest:
There, easy. Analysing the resulting profiling data is done by using pstats. I followed the directions laid out here: Handy Python profiling analysis with pstats’ interactive browser.