【发布时间】:2019-10-04 10:51:10
【问题描述】:
类方法TestCase.setUpTestData()
上述的类级别原子块允许在类级别创建初始数据,一次用于整个 TestCase。
[...]
注意不要在您的测试方法中修改 setUpTestData() 中创建的任何对象。在类级别完成的设置工作对内存中对象的修改将在测试方法之间持续存在。
城市。 django.test.TestCase.setUpTestData
考虑这个例子:
class FoobarTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.post = Post()
cls.post.stats = {}
cls.post.save()
def setUp(self):
self.post.refresh_from_db()
def test_foo(self):
self.post.stats['foo'] = 1
self.post.save()
self.assertEquals(self.post.stats, {'foo': 1}) # this should fail
def test_bar(self): # this run first cause alphabetical order
self.post.stats['bar'] = 1
self.post.save()
self.assertEquals(self.post.stats, {'bar': 1})
自从
在类级别完成的设置工作对内存中对象的修改将在测试方法之间持续存在
我预计两种测试方法中的一种会失败,因为 post 对象也将具有不同的属性,并且相等应该失败。
但是这个测试没有问题通过。
如果我强制执行顺序,它实际上表现得像预期的那样:
class FoobarTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.post = Post()
cls.post.stats = {}
cls.post.save()
def setUp(self):
self.post.refresh_from_db()
def _foo(self):
self.post.stats['foo'] = 1
self.post.save()
self.assertEquals(self.post.stats, {'foo': 1})
def _bar(self):
self.post.stats['bar'] = 1
self.post.save()
self.assertEquals(self.post.stats, {'bar': 1})
def test_foo_bar(self):
self._foo()
self._bar() # this fail
问题是:
在第一个示例中,测试方法是否以某种并行方式运行?他们真的会在一些与时间相关的巧合下失败吗?
关于 order in which tests are executed 的 Django 文档没有谈论测试方法。
在this post我发现测试方法的顺序是可以改变的,但是是一个接一个,没有并行性,除非我用python manage.py test --parallel。
【问题讨论】:
-
对于今天阅读这篇文章的任何人,Django 3.2+ 现在可以为您的数据库制作一个干净的副本,因此它们被清楚地分开docs.djangoproject.com/en/3.2/topics/testing/tools/…
-
setUpTestData 在数据库不支持事务的情况下为每个测试运行调用,例如MySQL,这也可以解释这种行为