В чем разница между setUp () и setUpClass () в Python unittest?

101

В чем разница между фреймворком Python setUp()и setUpClass()в нем unittest? Почему установка должна выполняться одним методом, а не другим?

Я хочу , чтобы понять , какая часть установки выполняется в setUp()и setUpClass()функциях, а также tearDown()и tearDownClass().

этя
источник

Ответы:

149

Разница проявляется, когда у вас есть более одного метода тестирования в вашем классе. setUpClassи tearDownClassвыполняются один раз для всего класса; setUpи tearDownвыполняются до и после каждого метода тестирования.

Например:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

Когда вы запускаете этот тест, он печатает:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(Точки ( .) являются unittest«ы выход по умолчанию , когда тест пройден) . Заметим , что setUpи tearDownпоявляются до и после , test1 и test2 , в то время как setUpClassи tearDownClassпоявляются только один раз, в начале и в конце всего теста.

Бенджамин Ходжсон
источник
Разве порядок не должен быть таким? : setUpClass setUp test1 tearDown .setUp test2 .tearDown tearDownClass
Джай Шарма
Обратите внимание на "." перед tearDown и отсутствием "." перед tearDownClass
Джай Шарма
Ах, извините, не заметил этого. Нет, unittestтест не считается пройденным до тех пор, пока он tearDownне прошел без происшествий.
Бенджамин Ходжсон
Итак, у каждого из методов test1 и test2 должен быть свой собственный набор setUp и tearDown, верно? В вашем ответе у test1 нет метода tearDown, поэтому он должен был распечатать результат по умолчанию (с.). Поправьте меня если я ошибаюсь.
Джай Шарма
1
Вывод в ответ правильный. Я вставил его прямо из вывода unittest. setUpи tearDownвыполняются один раз для каждого testметода (всего дважды в этом примере), но setUpClassи tearDownClassвыполняются каждый раз только один раз.
Бенджамин Ходжсон
15

В чем разница между фреймворком Python setUp()и setUpClass()в нем unittest?

Основное отличие (как отмечено в ответе Бенджамина Ходжсона) заключается в том, что он setUpClassвызывается только один раз, и это перед всеми тестами, а setUpвызывается непосредственно перед каждым тестом. (NB: то же самое относится к эквивалентным методам в других тестовых средах xUnit, а не только в Python unittest.)

Из unittest документации :

setUpClass()

Метод класса, вызываемый перед запуском тестов в отдельном классе. setUpClass вызывается с классом в качестве единственного аргумента и должен быть оформлен как classmethod ():

@classmethod
def setUpClass(cls):
    ...

и:

setUp()

Метод, вызываемый для подготовки тестового прибора. Это вызывается непосредственно перед вызовом тестового метода; кроме AssertionError или SkipTest, любое исключение, вызванное этим методом, будет считаться ошибкой, а не ошибкой теста. Реализация по умолчанию ничего не делает.

Почему установка должна выполняться одним методом, а не другим?

На эту часть вопроса пока нет ответа. Согласно моему комментарию в ответ на ответ Gearon, setUpметод предназначен для элементов приспособления, которые являются общими для всех тестов (чтобы избежать дублирования этого кода в каждом тесте). Я считаю, что это часто бывает полезно, поскольку удаление дублирования (обычно) улучшает читаемость и снижает нагрузку на обслуживание.

Этот setUpClassметод предназначен для дорогостоящих элементов, которые вы бы предпочли сделать только один раз, таких как открытие соединения с базой данных, открытие временного файла в файловой системе, загрузка разделяемой библиотеки для тестирования и т. Д. Выполнение таких действий перед каждым тестом замедлит работу набора тестов слишком много, поэтому мы просто делаем это один раз перед всеми тестами. Это небольшое снижение независимости тестов, но в некоторых ситуациях необходима оптимизация. Возможно, не следует делать такие вещи в модульных тестах, поскольку обычно можно имитировать базу данных / файловую систему / библиотеку / что угодно, не используя настоящую вещь. Таким образом, я считаю, что setUpClassэто редко требуется. Однако это полезно, когда возникает необходимость в тестировании приведенных выше (или аналогичных) примеров.

Biggsy
источник