3

I'm writing unit tests for my Python app with pytest. Most of my experience with unit test writing comes from Javacript frameworks such as Jasmine, where you can mark singly mark tests to run in next test round with word 'fit' or mark test to be excluded with word 'xit'. 'fit' is nice during development when I want to run only very specific subset of tests to reduce run time and results output clutter. Xit is already implemented with mark.skip decorator, but I'd like to have fit.

How I can configure pytest to do something like following:

  • Collect all tests
  • Check if there is any tests marked with decorator @pytest.mark.only decorator. If any is found, run only those tests, otherwise run all tests

I'm aware that I can select tests to run with command line with -m flag, but I'd like to dynamically detect the subset of runnable tests so that during development I don't have to run tests with two different commands with one having -m flag, and other without the flag.

I suppose conftest.py could be a place to add this logic but I couldn't find much information about the configuration of it.

Tumetsu
  • 1,661
  • 2
  • 17
  • 29

1 Answers1

5

Pytest plugin pytest_collection_modifyitems seems what you need. (put the following code in your conftest.py)

def pytest_collection_modifyitems(session, config, items):
    """ called after collection has been performed, may filter or re-order
    the items in-place."""

    found_only_marker = False
    for item in items.copy():
        if item.get_marker('only'):
            if not found_only_marker:
                items.clear()
                found_only_marker = True
            items.append(item)

list items are collected tests.

Notes: list.copy only works in python3, if you are using python2, please refer: How to clone or copy a list?

The idea is straightforward:

After collecting all tests(items), just check if marker 'only' exists in any test. If so, clear the list items and only add tests marked as only, if not, keep items as it is.

Community
  • 1
  • 1
Li Feng
  • 931
  • 6
  • 14