PyTest teardown_class запускается слишком рано

Python teardown_class ведет себя не так, как я ожидал. Ниже приводится краткое изложение моего кода:

@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"""

Я считаю, что способ его выполнения таков:

  1. create_table вызывается из настройки с 1-м параметром (table1)
  2. Код в create_table выполняется
  3. Код в teardown_class выполняется
  4. 1-3 выше снова выполняется со вторым параметром
  5. 1-3 выше снова выполняется с 3-м параметром
  6. Код в test_foo выполняется

Как я ожидаю, что это будет работать:

  1. create_table вызывается с 1-м параметром (table1)
  2. Код в create_table выполняется
  3. create_table вызывается со вторым параметром (таблица 2)
  4. Код в create_table выполняется
  5. create_table вызывается с 3-м параметром (таблица 3)
  6. Код в create_table выполняется
  7. Код в test_foo выполняется
  8. Код в teardown_class выполняется

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


person user1599401    schedule 27.06.2018    source источник


Ответы (2)


В вашем методе класса отсутствует параметр cls:

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

Измените это на

@classmethod
    def create_table(cls, some_arg_here):

Я изменил ваш код и добавил несколько отпечатков:

class TestClass:

    @classmethod
    def setup_class(cls):
        print("Setting up")
        cls.create_table('table1')
        cls.create_table('table2')
        cls.create_table('table3')

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

    def test_foo(self):
        print('Running test_foo')
        """Some test code here"""

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

Если вы запустите его с -s, вы получите следующий результат:

test.py Setting up
Creating: table1
Creating: table2
Creating: table3
Running test_foo
.Tearing down

Как видите, все работает как положено. Вызывается setup_class, создаются таблицы (все 3), запускается метод тестирования, а затем запускается teardown_class.

Если вы добавите функцию test_bar (), вы получите:

test.py Setting up
Creating: table1
Creating: table2
Creating: table3
Running test_foo
.Running test_bar
.Tearing down

Мне тоже кажется, что это нормально ...

У вас есть еще несколько подсказок в пользу вашего предположения, что что-то не так?

person butterfly_princess    schedule 27.06.2018
comment
Я обнаружил, что проблема возникает, когда я вызываю другой метод из метода настройки. Если я помещаю код из create_table непосредственно в метод настройки, он работает должным образом: выполняется весь код в методе настройки, затем выполняется тест, а затем выполняется разборка. Но если я вызываю create_table из настройки (несколько раз), то после каждого вызова запускается разборка. Неужели это так, как ожидается? Если да, мне нужно обходное решение ... - person user1599401; 28.06.2018

Я смог найти решение. Я воссоздал функцию create_table как внутреннюю функцию внутри функции setup.

@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"""

И теперь он работает так, как я ожидал, в такой последовательности:

  1. Выполнить create_table один раз для параметра table1
  2. Выполнить create_table один раз для параметра table2
  3. Выполнить create_table один раз для параметра table3
  4. Запустите test_foo
  5. Запустите teardown_class

Кажется, что каждый / каждый раз, когда функция, которая находится за пределами setup, вызывается из setup, это приводит к тому, что функция teardown запускается непосредственно после выполнения кода во внешней функции, и это была проблема, с которой я столкнулся облицовка.

person user1599401    schedule 28.06.2018