It's not uncommon for there to be set-up code that can't run as a class method. One notable example is the Django test client: you might not want to reuse the same client instance across tests that otherwise share much of the same data, and indeed, the client instances automatically included in subclasses of Django's SimpleTestCase
are created per test method rather than for the entire class. Suppose you had a test from the pre-Django 1.8 world with a setUp
method like this:
def setUp(self):
self.the_user = f.UserFactory.create()
self.the_post = f.PostFactory.create(author=self.the_user)
self.client.login(
username=self.the_user.username, password=TEST_PASSWORD
)
# ... &c.
You might tempted to modernize the test case by changing setUp
to setUpTestData
, slapping a @classmethod
decorator on top, and changing all the self
s to cls
. But that will fail with a AttributeError: type object 'MyTestCase' has no attribute 'client'
! Instead, you should use setUpTestData
for the shared data and setUp
for the per-test-method client:
@classmethod
def setUpTestData(cls):
cls.the_user = f.UserFactory.create()
cls.the_post = f.PostFactory.create(author=cls.the_user)
# ... &c.
def setUp(self):
self.client.login(
username=self.the_user.username, password=TEST_PASSWORD
)
Note: if you are wondering what that variable f is doing in the example code, it comes from factoryboy - a useful fixtures library for creating objects for your tests.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…