Sharad
Sharad

Reputation: 10602

How to specify custom marker with py.test command line with sub-set of attributes?

I'd like to define a custom marker (my_marker containing a bunch of attributes. While triggering the tests, how do I select/specify a set of tests with a specific attribute?

For e.g., consider the following:

import pytest

@pytest.mark.my_marker(foo='bar')
def test_001():
    pass 

def test_002():
    pass

@pytest.mark.my_marker(foo='bar', cat='dog')
def test_003():
    pass

Now, py.test -m my_marker will select test_001 and test_003. I'd like to specify something like:

py.test -s -m "my_marker(cat='dog')"

This should select only test_003. But py.test throws an error with this. Any suggestions?

Regards

Sharad

Upvotes: 0

Views: 1372

Answers (1)

Sharad
Sharad

Reputation: 10602

I was able to get reasonably close with this:

conftest.py

import ast
import pytest

def pytest_collection_modifyitems(session, config, items):
    mymarkerFilter = config.option.markexpr
    if not mymarkerFilter:
        return
    mymarkerFilter = ast.literal_eval(mymarkerFilter).get('my_marker')
    if not mymarkerFilter:
        return

    selected = []
    deselected = []
    for item in items:
        testMymarker = item.get_marker('my_marker')
        if not testMymarker:
            deselected.append(item)
            continue
        found = False
        for filterKey in mymarkerFilter:
            if not testMymarker.kwargs.get(filterKey):
                deselected.append(item)
                found = True
                break
            if mymarkerFilter[filterKey] != testMymarker.kwargs.get(filterKey):
                deselected.append(item)
                found = True
                break
        if not found:
            selected.append(item)
    if deselected:
        config.hook.pytest_deselected(items=deselected)
        items[:] = selected
    print('Deselected: {}'.format(deselected))
    print('Selected: {}'.format(items))

test_bar.py

import pytest

@pytest.mark.my_marker(foo='bar')
def test_001():
    print('test_001')

def test_002():
    print('test_002')

@pytest.mark.my_marker(foo='bar', cat='dog')
def test_003():
    print('test_003')

Output


# Without specifying any marker

py.test -vs test_bar.py

Test session starts (platform: linux, Python 3.5.1, pytest 2.8.7, pytest-sugar 0.5.1)
cachedir: .cache
rootdir: /home/sharad/tmp, inifile: 
plugins: cov-2.2.1, timeout-1.0.0, sugar-0.5.1, json-0.4.0, html-1.8.0, spec-1.0.1

 test_bar.pytest_001                                                                                                                                                                                                       0%           test_001
 test_bar.pytest_001 ✓                                                                                                                                                                                                    33% ███▍      
 test_bar.pytest_002                                                                                                                                                                                                      33% ███▍      test_002
 test_bar.pytest_002 ✓                                                                                                                                                                                                    67% ██████▋   
 test_bar.pytest_003                                                                                                                                                                                                      67% ██████▋   test_003
 test_bar.pytest_003 ✓                                                                                                                                                                                                   100% ██████████

Results (0.06s):
       3 passed

# Specifying foo=bar

py.test -vs -m "{'my_marker': {'foo': 'bar'}}" test_bar.py

Test session starts (platform: linux, Python 3.5.1, pytest 2.8.7, pytest-sugar 0.5.1)
cachedir: .cache
rootdir: /home/sharad/tmp, inifile: 
plugins: cov-2.2.1, timeout-1.0.0, sugar-0.5.1, json-0.4.0, html-1.8.0, spec-1.0.1
Deselected: [<Function 'test_002'>]
Selected: [<Function 'test_001'>, <Function 'test_003'>]

 test_bar.pytest_001                                                                                                                                                                                                       0%           test_001
 test_bar.pytest_001 ✓                                                                                                                                                                                                    50% █████     
 test_bar.pytest_003                                                                                                                                                                                                      50% █████     test_003
 test_bar.pytest_003 ✓                                                                                                                                                                                                   100% ██████████
=================================================================================== 1 tests deselected by '-m "{\'my_marker\': {\'foo\': \'bar\'}}"' ===================================================================================

Results (0.04s):
       2 passed
       1 deselected

# Specifying foo=bar, cat=dog

py.test -vs -m "{'my_marker': {'foo': 'bar', 'cat': 'dog'}}" test_bar.py

Test session starts (platform: linux, Python 3.5.1, pytest 2.8.7, pytest-sugar 0.5.1)
cachedir: .cache
rootdir: /home/sharad/tmp, inifile: 
plugins: cov-2.2.1, timeout-1.0.0, sugar-0.5.1, json-0.4.0, html-1.8.0, spec-1.0.1
Deselected: [<Function 'test_001'>, <Function 'test_002'>]
Selected: [<Function 'test_003'>]

 test_bar.pytest_003                                                                                                                                                                                                       0%           test_003
 test_bar.pytest_003 ✓                                                                                                                                                                                                   100% ██████████
========================================================================== 2 tests deselected by '-m "{\'my_marker\': {\'foo\': \'bar\', \'cat\': \'dog\'}}"' ==========================================================================

Results (0.06s):
       1 passed
       2 deselected

Upvotes: 3

Related Questions