Определение тестовых методов в базовом классе, которые не должны быть инстанцированы напрямую
Я пытаюсь создать тестовые случаи, которые отличаются только тем, какой пользователь вошел в систему.
Поэтому я решил, что определение тестов в базовом классе и создание подклассов, которые регистрируют пользователя во время setUp()
, будет правильным решением.
Однако я не могу найти элегантное решение для исключения тестов в базовом классе из выполнения.
from django.contrib.auth.models import User
from django.test import TestCase
class A(TestCase):
@classmethod
def setUpTestData(cls):
cls.user_a = User.objects.create_user("a", "", "a")
cls.user_b = User.objects.create_user("b", "", "b")
def setUp(self):
# global set up stuff here
...
def test_1(self):
self.assertEqual(self.user_a.username, "a")
class SubA(A):
def setUp(self):
super().setUp()
self.client.force_login(self.user_a)
class SubB(A):
def setUp(self):
super().setUp()
self.client.force_login(self.user_b)
В приведенном выше коде я хочу, чтобы выполнялись только унаследованные тесты в классах SubA
и SubB
, но не тесты в A
.
Я пробовал:
- Извлечение базового класса в другой модуль, который не включен в шаблон поиска по умолчанию. => все равно выполняются тесты, поскольку базовый класс должен быть импортирован, чтобы наследоваться от него .
- определение
load_tests(...)
функции в пакете, исключающем базовый класс => тот же результат, что и выше - повышение
unittest.SkipTest
в базовом классеsetUp()
и перехват его в подклассахsetUp
=> работает, но добавляет все тесты в базовом классе как "пропущенные"
Итак, мой вопрос заключается в следующем:
Есть ли способ исключить тесты в базовом классе (который должен наследоваться от TestCase
Django) из выполнения без записи их как пропущенных и, желательно, без необходимости дополнительных параметров в моей команде ./manage.py test
?
Может быть, использовать средства subTest
тестового фреймворка?
class A(TestCase):
... # setups as before
def test1( self):
for user in ( self.user_a, self.user_b):
with self.subTest( user=user):
self.client.force_login( user)
# and now the test(s) that you want to execute both for user_a and user_b
self.assertEqual(user.username, "a")
Если подтест проваливается, содержащий его тест не останавливается, а начинается следующий подтест в итерации. kwarg к self.subTest выводится как часть сообщения о неудаче подтеста. Если (как в данном случае) переданная сущность не является строкой, она преобразуется в str. Если это приведет к неудаче или выдаст глупый вывод, вы можете выполнить собственное преобразование, например self.subTest( user=f"{user.username} (pk={user.pk})" )
(если вы видели это пять минут назад, я удалил свое другое предложение, потому что, поразмыслив, я не увидел, что оно может быть полезным. Если я ошибаюсь, предложение состояло в том, что вы могли бы поместить тестовые процедуры в класс mixin, производный от object
, и наследовать их в классах TestCase A
и B
)