Персистентная переменная изменяется между тестами в unittest?
Как сохранить изменения, сделанные внутри одного объекта, наследующего от TestCase
в unitttest?
from unittest import TestCase, main as unittest_main
class TestSimpleFoo(TestCase):
foo = 'bar'
def setUp(self):
pass
def test_a(self):
self.assertEqual(self.foo, 'bar')
self.foo = 'can'
def test_f(self):
self.assertEqual(self.foo, 'can')
if __name__ == '__main__':
unittest_main()
I.e: Я хочу, чтобы эти два теста выше проходили
Ответы
Ответ 1
Как уже отмечалось в некоторых комментариях, структурирование ваших тестов таким образом, вероятно, является конструктивным недостатком самих тестов, и вы должны рассмотреть возможность их реструктуризации. Однако, если вы хотите сделать это и полагаться на то, что используемый вами тестовый бегущий выполняет их в алфавитном порядке (по-видимому), я предлагаю следующее.
Подобно тому, что говорил @Matthias, но я бы сделал одну вещь по-разному в тех случаях, когда вы можете решить наследовать от класса на более позднюю дату.
from unittest import TestCase, main as unittest_main
class TestSimpleFoo(TestCase):
foo = 'bar'
def setUp(self):
pass
def test_a(self):
self.assertEqual(self.__class__.foo, 'bar')
self.__class__.foo = 'can'
def test_f(self):
self.assertEqual(self.__class__.foo, 'can')
if __name__ == '__main__':
unittest_main()
Разница между этим ответом и ответом @Matthias на то, что вы приняли, - это явное объявление класса по сравнению с поиском указанной ссылки на класс.
TestSimpleFoo vs self.__class__
Я предпочитаю динамику, поэтому я могу наследовать тесты позже и запускать оба тестовых класса назад и не перекрещиваться между ними. Поскольку, если вы захотите наследовать от этого класса, явное назначение ссылки на класс приведет к тому, что оба тестовых класса будут выполняться против этой ссылки, а не их собственные соответствующие классы.
Ответ 2
Мне нравится ваш собственный ответ на простоту, но если вы хотите сохранить отдельные модульные тесты:
Очевидно, unittest запускает отдельные тесты со свежими экземплярами TestCase. Ну, просто привяжите объекты к чему-то еще, кроме себя. Например:
from unittest import TestCase, main as unittest_main
class TestSimpleFoo(TestCase):
def setUp(self):
pass
def test_a(self):
TestSimpleFoo.foo = 'can'
def test_f(self):
self.assertEqual(TestSimpleFoo.foo, 'can')
if __name__ == '__main__':
unittest_main()
Вы можете быть заинтересованы в setUpClass и tearDownClass:
https://docs.python.org/3/library/unittest.html#setupclass-and-teardownclass
Также соблюдайте порядок выполнения ваших модульных тестов:
https://docs.python.org/2/library/unittest.html#unittest.TestLoader.sortTestMethodsUsing
Ответ 3
Не мог понять это; так что в итоге он взломал несколько префиксов, отличных от test_
:
def test_password_credentials_grant(self):
for user in self.user_mocks:
self.register(user)
self.login(user)
self.access_token(user, self.assertEqual) # Ensures access_token is generated+valid
self.logout(user)
self.access_token(user, self.assertNotEqual) # Ensures access_token is now invalid
self.unregister(user)