Python 使用setUpTestData的Django测试不';不要在测试之间保持更改

Python 使用setUpTestData的Django测试不';不要在测试之间保持更改,python,django,testing,Python,Django,Testing,ClassMethodTestCase.setUpTestData()方法 上面描述的类级原子块允许在类级创建初始数据,一次用于整个测试用例 [……] 小心不要在测试方法中修改在setUpTestData()中创建的任何对象。在类级别完成的设置工作对内存中对象的修改将在测试方法之间保持不变 Cit 考虑这个例子: class FoobarTest(TestCase): @classmethod def setUpTestData(cls): cls.post =

ClassMethodTestCase.setUpTestData()方法

上面描述的类级原子块允许在类级创建初始数据,一次用于整个测试用例

[……]

小心不要在测试方法中修改在setUpTestData()中创建的任何对象。在类级别完成的设置工作对内存中对象的修改将在测试方法之间保持不变

Cit

考虑这个例子:

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
    self.assertEquals(self.post.stats, {'bar': 1})
AssertionError: {'foo': 1, 'bar': 1} != {'bar': 1}
- {'bar': 1, 'foo': 1}
+ {'bar': 1}
问题是:

在第一个示例中,测试方法是否以某种并行方式运行?在某些与时间相关的巧合下,它们真的会失败吗

Django文档中关于测试方法的内容没有提及


在中,我发现测试方法的顺序可以更改,但是是一个接一个的,没有并行性,除非我使用
python manage.py test--parallel
这是我的测试,使用内存而不是数据库:

from django.test import TestCase

class Post(object):
    def __init__(self):
        self.stats = {}

    def refresh_from_db(self):
        pass

    def save(self):
        pass


class FoobarTest(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.post = Post()
        cls.post.stats = {}

    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})
这是我的结果:

    self.assertEquals(self.post.stats, {'foo': 1})  # this should fail
AssertionError: {'bar': 1, 'foo': 1} != {'foo': 1}
- {'bar': 1, 'foo': 1}
+ {'foo': 1}
将方法
foo
更改为
afoo
,结果与预期一致:

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
    self.assertEquals(self.post.stats, {'bar': 1})
AssertionError: {'foo': 1, 'bar': 1} != {'bar': 1}
- {'bar': 1, 'foo': 1}
+ {'bar': 1}
也许这是个数据库问题

在您的断言中,您正在检查内存对象:如果
save
失败,
refresh\u from\u db
返回开始的空对象,因此下一次检查通过


保存
后尝试获取数据,然后检查它们。

在示例中,如果
保存
失败,我希望收到异常。另外,在“真实”代码中,我检查了这一点,没有保存错误。我认为接收到异常以及您正在经历的所有这些都属于模型实现或数据库/驱动程序问题。