Django, когда использовать метод teardown

Согласно документам:

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

Итак, если у меня есть тест, который выглядит так:

class GeneralUserCreateTest(TestCase):

    def setUp(self):
        create_roletypes()
        create_permissiontypes()
        self.client = Client()
        self.event = create_event()

    def test_create(self):
        create_url = reverse('event_user_signup', args=[self.event.slug])

        post_data = {
            'signup-account-email': '[email protected]',
            'signup-account-password': 'foobar',
            'signup-account-password2': 'foobar',
            'signup-account-first_name': 'Foo',
            'signup-account-last_name': 'Bar',
        }
        response = self.client.post(create_url, data=post_data)
        self.assertEqual(response.status_code, 302)

        # check creation of user object
        self.assertEqual(User.objects.filter(email=post_data['signup-account-email']).count(), 1)
        user = User.objects.get(username=post_data['signup-account-email'])

        # user and profile objects created
        self.assertEqual(User.objects.all().count(), 1)
        self.assertEqual(Profile.objects.all().count(), 1)

        # get the first user and profile object to test against submitted field
        user = User.objects.all()[0]
        profile = Profile.objects.all()[0]
        role = Role.objects.filter(event=self.event, profiles=profile)[0]
        self.assertEqual(role.roletype.name, 'General')
        self.assertEqual(user.username, post_data['signup-account-email'])
        self.assertEqual(user.email, post_data['signup-account-email'])
        self.assertEqual(profile.first_name, post_data['signup-account-first_name'])
        self.assertEqual(profile.last_name, post_data['signup-account-last_name'])

Необходимо ли все-таки запустить метод teardown или класс TestCase позаботится об этом? Если да, то когда следует использовать метод teardown, учитывая доступность класса TestCase?

Ответы

Ответ 1

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

Ответ 2

Я работал над проектом, который обрабатывал некоторые загрузки файлов, и мне нужно было удалить файлы, созданные с помощью теста, и метод tearDown был очень полезен в этой ситуации.

import shutil

#....
#....

    def tearDown(self):
        shutil.rmtree(settings.UPLOAD_ROOT)

Ответ 3

Если вы используете альтернативную базу данных, такую ​​как MongoDB или Redis, и вам нужно загрузить в набор исходных данных ( "коллекция" ), вам также необходимо переопределить метод tearDown.

См. http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/

В общем, django.test.TestCase выполняет полную загрузку базы данных в начале каждого новый тест. Это означает, что нам не нужно вручную удалять объекты в нашем tearDown, как упоминал выше Крис Пратт. Следующий тестовый наборUp гарантирует, что база данных будет чистой.

Однако, если мы используем doctests и unittest.TestCase, перед запуском тестов снова не будет сбрасываться база данных. В начале теста база данных будет в любом состоянии предыдущего тест влево. Это означает, что любые блуждающие данные, оставленные предыдущим запуском, вызовут конфликт. Поэтому, если мы используем doctests или unittest.TestCase для наших тестов django, очистка может быть хорошей практикой.

Наконец, в более сложных сценариях также может быть целесообразно намеренно сохранить тестовую базу данных для поиска определенных ошибок unit test.