pytest-dev / pytest-dev/pytest

'class' scope fixture invoke and teardown order issue in nested test class

Open
#5,148 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: fixtures
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

Details

fixture name invoked and teardown every subclass method as I expect.

class TestClassTop:
    @pytest.fixture(scope='class')
    def name(self):
        print('   <<<< Invoke Name')
        yield
        print('   <<<< tear down')

    # def test_method_sub(self, name):  <--  comment it out
    #     pass

    class TestSubClassA:
        def test_sub_cls_method(self, name):
            pass

    class TestSubClassB:
        def test_sub_cls_method(self, name):
            pass

>>>
test_cls.py::TestClassTop::TestSubClassA::test_sub_cls_method    <<<< Invoke Name
PASSED   <<<< tear down

test_cls.py::TestClassTop::TestSubClassB::test_sub_cls_method    <<<< Invoke Name
PASSED   <<<< tear down

but fixture name invoked in TestClassTop.test_method_sub but teardown in TestClassTop.TestSubClassA.test_sub_cls_method

class TestClassTop:
    @pytest.fixture(scope='class')
    def name(self):
        print('   <<<< Invoke Name')
        yield
        print('   <<<< tear down')

    def test_method_sub(self, name):  # <--  uncomment it
        pass

    class TestSubClassA:
        def test_sub_cls_method(self, name):
            pass

    class TestSubClassB:
        def test_sub_cls_method(self, name):
            pass
>>>
test_cls.py::TestClassTop::test_method_sub    <<<< Invoke Name
PASSED
test_cls.py::TestClassTop::TestSubClassA::test_sub_cls_method PASSED   <<<< tear down

test_cls.py::TestClassTop::TestSubClassB::test_sub_cls_method    <<<< Invoke Name
PASSED   <<<< tear down

And If I move TestClassTop.test_method_sub to the bottom, the result seems right.

class TestClassTop:
    @pytest.fixture(scope='class')
    def name(self):
        print('   <<<< Invoke Name')
        yield
        print('   <<<< tear down')

    class TestSubClassA:
        def test_sub_cls_method(self, name):
            pass

    class TestSubClassB:
        def test_sub_cls_method(self, name):
            pass

    def test_method_sub(self, name):
        pass
>>>
 test_cls.py::TestClassTop::TestSubClassA::test_sub_cls_method    <<<< Invoke Name
PASSED   <<<< tear down

test_cls.py::TestClassTop::TestSubClassB::test_sub_cls_method    <<<< Invoke Name
PASSED   <<<< tear down

test_cls.py::TestClassTop::test_method_sub    <<<< Invoke Name
PASSED   <<<< tear down


Environment

Python 3.6.8
Mac OS High Sierra 10.13.6

Package        Version 
-------------- --------
pytest         4.4.0   
atomicwrites   1.3.0   
attrs          19.1.0  
autopep8       1.4.4   
certifi        2019.3.9
chardet        3.0.4   
idna           2.8     
Jinja2         2.10.1  
MarkupSafe     1.1.1   
more-itertools 7.0.0   
peewee         3.9.4   
pip            18.1    
pluggy         0.9.0   
prettytable    0.7.2   
py             1.8.0   
pycodestyle    2.5.0   
PyJWT          1.7.1   
PyMySQL        0.9.3   
redis          3.2.1   
requests       2.21.0  
retrying       1.3.3   
setuptools     40.6.2  
six            1.12.0  
treker         0.0.2   
urllib3        1.24.1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the nested fixture cases in test_cls.py using the issue's Python examples and compare teardown order when test_method_sub is first or last. Start by tracing pytest's class-scoped fixture setup and teardown ordering for nested test classes. Done means the fixture teardown consistently occurs after the tests in the intended scope, with regression coverage for both method orders.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.