2015-04-03 199 views

回答

20

有一些设置代码无法作为类方法运行,这并不罕见。一个值得注意的例子是Django test client:您可能不希望在测试中重复使用相同的客户端实例,否则这些测试会共享大部分相同的数据,事实上,自动包含在Django的SimpleTestCase的子类中的客户端实例为created per test method而非整个类。假设你有从前期的Django 1.8世界的一个测试用setUp方法是这样的:

 
    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. 

你可能很想通过改变setUpsetUpTestData,在上面掴一名@classmethod装饰,并改变所有测试用例现代化self s到cls。但是,这将失败,AttributeError: type object 'MyTestCase' has no attribute 'client'!相反,你应该使用setUpTestData的共享数据和setUp为每个测试方法的客户:

 
    @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 
     ) 
+1

值得从这种方法中添加更多的细节https://makina-corpus.com/blog/metier/2015/how-to-optimize-django-unit-tests-with-setuptestdata。如果您的测试数据每次测试都有变化,只要您在'setUp'中执行'self.model.refresh_from_db()',您仍然可以在'setUpTestData'中创建可变模型。来自TC的更改会回滚,但如果没有手动步骤,self.model会引用上一次运行的数据。使用setUp步骤,您可以对每个测试用例执行一次读取,但通常这比对每个测试用例写入要快。 – Symmetric 2017-07-28 17:00:38

4

缓存的问题。即使Django在事务回滚提供测试隔离方面做得更好,仍然会手动生成并清除缓存。

[编辑]: SetUpTestData定义了数据库在每次测试后将被恢复到的状态,并且只用一次执行的方法执行,事务回滚在Django幕后完成。这对高速缓存不起作用。如果您希望每个测试的缓存都相同,则需要在每次测试之间重置缓存,因此需要setUp。 Django可以回滚数据库,但不能回滚所有内容。

(谢谢布莱恩 - 奥克利的建议)

+0

这似乎无法回答所问的问题。 – 2016-03-24 17:33:10

+0

SetUpTestData定义每次测试后数据库将恢复到的状态,并使用只执行一次的方法执行此操作,事务回滚由Django完成。这对高速缓存不起作用。如果您希望每个测试的缓存都相同,则需要在每次测试之间重置缓存,因此需要setUp。 Django可以回滚数据库,但不能回滚所有内容。 – 2016-10-05 07:36:36

+0

你应该让你的评论成为答案的一部分,因为它使答案更容易理解。 – 2016-10-05 10:49:34