pythongoogle-bigquerypytestteardown

PyTest teardown_class is being run too soon


The Python "teardown_class" is not behaving as I expect it to. Below is a summary of my code:

@classmethod
def setup_class(cls):
    cls.create_table(table1)
    cls.create_table(table2)
    cls.create_table(table3)

@classmethod
def create_table(cls, some_arg_here):
    """Some code here that creates the table"""

def test_foo(self):
    """Some test code here"""

@classmethod
def teardown_class(cls):
    """Perform teardown things"""

I believe the way it is executing is that:

  1. create_table is being called from setup with 1st parameter (table1)
  2. Code in create_table executes
  3. Code in teardown_class executes
  4. 1-3 above is executed again with the 2nd parameter
  5. 1-3 above is executed again with the 3rd parameter
  6. Code in test_foo executes

How I expect it to perform:

  1. create_table is called with 1st parameter (table1)
  2. Code in create_table executes
  3. create_table is called with 2nd parameter (table 2)
  4. Code in create_table executes
  5. create_table is called with 3rd parameter (table 3)
  6. Code in create_table executes
  7. Code in test_foo executes
  8. Code in teardown_class executes

Python 2.7.10, pytest-3.6.2, py-1.5.3, pluggy-0.6.0


Solution

  • I was able to find the solution. I recreated the create_table function as an inner function, inside of the setup function.

    @classmethod
    def setup_class(cls):
        def create_table(some_arg_here):
           """Some code here that creates the table"""
    
        create_table(table1)
        create_table(table2)
        create_table(table3)
    
    def test_foo(self):
        """Some test code here"""
    
    @classmethod
    def teardown_class(cls):
        """Perform teardown things"""
    

    And now it runs as I expect it to, in this sequence:

    1. Run create_table once for table1 param
    2. Run create_table once for table2 param
    3. Run create_table once for table3 param
    4. Run test_foo
    5. Run teardown_class

    It seems that any/every time a function that is outside of setup is called from setup, it causes the teardown function to run directly after the code in the outer function runs, and that was the issue I was facing.