I am trying to create test cases which only differ by which user is logged in.
Therefore I figured defining the tests in a base class and creating sub classes which log in the user during setUp()
would be the way to go.
However I cannot find an elegant solution to excluding the tests in the base class from running.
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)
In the code above I'd want only the inherited tests in the classes SubA
and SubB
to run, but not the one in A
.
I have tried:
load_tests(...)
function in the package which excludes the base class
=> same result as aboveunittest.SkipTest
in the base class setUp()
and catching it in the sub classes' setUp
=> works but adds all tests in the base class as "skipped"So my question is:
Is there a way to exclude the tests in a base class (which must inherit from Django's TestCase
) from running without recording them as skipped and, preferably, without the need for additional parameters to my ./manage.py test
command?
Maybe use the subTest
facility of the test framework?
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")
If a subtest fails, the test containing it does not stop and the next subtest in the iteration starts. The kwarg to self.subTest is printed as part of the subtest failure message. If (as here) the passed entity is not a string, it's converted to str. If this will fail or generate stupid output you would do your own conversion, such as self.subTest( user=f"{user.username} (pk={user.pk})" )
(if you saw this five minutes ago, I have deleted my other suggestion because on reflection I didn't see it would be helpful. In case I am wrong, the suggestion was that you could put the test routines in a mixin class derived from object
, and inherit them into the TestCase classes A
and B
)