Testing and profiling Python code simultaneously using pytest and cProfile

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

py.test test_X.py

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:

pytest.main(__file__)

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s