Skipping slow test by default in py.test

If you got a test suite that runs some very slow tests it might be troublesome to run those all the time. There is of course the "-k" option to py.test which allows you to selectively enable only a few tests. But what I really wanted was a way to have it skip slow tests by default but still allow me to enable slow tests with a command line option.

But this is not impossible, py.test provides a couple of things that make it possible to do this surprisingly easy:

So how do you pull this together? I decided that i want to mark slow tests using the "slow" keyword (@py.test.mark.slow) and skip those tests by default. And the option to enable those tests would be called "--slow". The following is staggeringly simple:

import py.test

def pytest_addoption(parser):
    parser.addoption('--slow', action='store_true', default=False,
                      help='Also run slow tests')

def pytest_runtest_setup(item):
    """Skip tests if they are marked as slow and --slow is not given"""
    if getattr(item.obj, 'slow', None) and not item.config.getvalue('slow'):
        py.test.skip('slow tests not requested')

Finding this solution was a little harder however, but essentially it involved nothing more then looking at the pytest_skipping and pytest_mark plugins to figure out what APIs the various objects provide. But it must be said that extending py.test is staggeringly simple, I tend to expect a much higher learning curve when I decide that I want to write a plugin for some tool I use.