question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Combining `pytest.skip` and `request.getfixturevalue` in multiple `pytest_runtest_setup`s causes AssertionError during TearDown

See original GitHub issue

Summary:

I'm using 2 plugins, each of which have `pytest_runtest_setup` hooks. One is used to get a fixture, and skip the test based on the value of a fixture. The second uses the `record_xml_attribute` fixture to add some attributes to my junitxml file (even if the test is skipped). The result of this is an AssertionError during TearDown. However, as seen in my example code, this is reproducible with any `function` and `session` scoped fixtures.

Assert being hit: _pytest/runner.py line 328

assert (colitem is None or colitem in self.stack or                                                                                                                                                   
                      isinstance(colitem, tuple))

The assertion is failing because colitem is of type _pytest.main.Session

pip list:

Package        Version
-------------- -------
atomicwrites   1.1.5  
attrs          18.1.0 
delayed-assert 0.1    
more-itertools 4.3.0  
pip            10.0.1 
pluggy         0.7.1  
py             1.5.4  
pytest         3.8.2  
setuptools     39.0.1 
six            1.11.0 

OS: Ubuntu 16.04

Minimal Example:

conftest.py:

import pytest                                                                                                                                                                                                       
                                                                                                                                                                                                                    
def pytest_runtest_setup(item):                                                                                                                                                                                     
    item._request.getfixturevalue('function_fixture')                                                                                                                                                               
    pytest.skip('Skip Reason')                                                                                                                                                                                      
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    
@pytest.fixture                                                                                                                                                                                                     
def function_fixture():                                                                                                                                                                                             
    pass

tests/conftest.py

                                                                                                                                                                                                                    
def pytest_runtest_setup(item):                                                                                                                                                                                     
    item._request.getfixturevalue('session_fixture')                                                                                                                                                                
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    
@pytest.fixture(scope='session')                                                                                                                                                                                    
def session_fixture(request):                                                                                                                                                                                       
    pass

tests/test_thing.py

def test_something():                                                                                                                                                                                               
    pass

Running py.test -svv . from the base directory results in an AssertionError being raised from /_pytest/runner.py line 328, in _teardown_with_finalization

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
RonnyPfannschmidtcommented, Oct 12, 2018

i believe the flow is completely unsupported and its entirely sensible we fall flat, however i haven’t seen the actual original traceback ^^

0reactions
asottilecommented, Oct 12, 2018

@mctwynne this appears to work, but I don’t know your usecase to know if it satisfies it:

import pytest


x = []

@pytest.fixture
def sometimes_fixture():
    x[:] = [1, 2, 3]
    yield
    x[:] = []


@pytest.fixture(autouse=True)
def autofix(request):
    marker_names = {m.name for m in request.node.iter_markers()}
    if 'sometimes_please' in marker_names:
        request.getfixturevalue('sometimes_fixture')
    if 'but_also_skip_ok' in marker_names:
        pytest.skip('plz skip!')


@pytest.mark.sometimes_please
def test_1():
    assert x == [1, 2, 3]


def test_2():
    assert x == []


@pytest.mark.sometimes_please
@pytest.mark.but_also_skip_ok
def test_3():
    raise AssertionError('I should have been skipped!')
 pytest test.py
============================= test session starts ==============================
platform linux -- Python 3.6.6, pytest-3.8.2, py-1.7.0, pluggy-0.7.1
rootdir: /tmp/pytest, inifile: tox.ini
collected 3 items                                                              

test.py ..s                                                              [100%]
=========================== short test summary info ============================
SKIP [1] /tmp/pytest/test.py:20: plz skip!

===================== 2 passed, 1 skipped in 0.03 seconds ======================
Read more comments on GitHub >

github_iconTop Results From Across the Web

how to skip teardown upon assertion in pytest
I would like to achieve this through conftest.py so that it won't effect the existing test cases. conftest.py import pytest @pytest.hookimpl( ...
Read more >
How to use fixtures
At a basic level, test functions request fixtures they require by declaring ... Two different tests can request the same fixture and have...
Read more >
pytest Documentation
For this reason, making multiple calls to pytest.main() from ... module: the fixture is destroyed during teardown of the last test in the ......
Read more >
pytest-steps
This is particularly helpful if: you wish to share a state / intermediate results across test steps; your tests already rely on other...
Read more >
unittest — Unit testing framework
Source code: Lib/unittest/__init__.py(If you are already familiar with the basic concepts of testing, you might want to skip to the list of assert...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found