单元测试如何/为什么在TestCase中相互影响以及如何防止这种行为?

时间:2018-04-09 07:07:16

标签: django python-3.x unit-testing django-unittest

我正在为使用Python3.6 / Django 2.0制作的webapp编写测试,我有以下情况:

class TestFoo(TestCase):
    def test_a(self):
        obj = Foo.objects.create(a = "bar")
        expectation = {"a" : "bar"}
        self.assertEquals(obj.method_x(), expectation)

    def test_b(self):
        obj = Foo.objects.create(a = "baz")
        expectation = {"a" : "baz"}
        self.assertEquals(obj.method_x(), expectation)

    def test_c(self):
        obj = Foo.objects.create(a = "bar")
        obj2 = Foo.objects.create(a = "baz")
        obj.b.add(obj2)
        expectation = {"a" : "bar", "b" : {"a": "baz"}}
        self.assertEquals(obj.method_x(), expectation)

据我所知,每个测试都是孤立运行的,但当我将test_c与测试a或b一起运行时,所有测试都会失败。基本上这个:

  • test_a + test_b + test_c = ALL FAIL
  • test_a + test_b = ALL PASS
  • test_c = ALL PASS
  • test_a + test_c = ALL FAIL
  • test_b + test_c = ALL FAIL

我试过了:

  1. 删除拆解中的所有Foo对象(如果没有发生这种情况), 这没效果
  2. 使用patch.object,但这不是我想要的行为,因为我想测试方法是否正常工作
  3. 在单独的类中粘贴test_c,这没有效果
  4. 以特定顺序运行测试(a,然后是b,然后是c和第一个c,然后是a / b,这会导致不同的故障点;如果我先运行c,它会通过,那么a / b就会失败。如果我先运行a / b,那么c会失败
  5. 我不确定导致此行为的原因,但我想解决它;我知道所有的测试都应该通过。我一直在阅读有关模拟/补丁方法的内容,但我很确定这不是我需要的,因为我需要验证我的对象的方法是否返回有效数据,而不是确保它们被调用或类似的东西。

    所以基本上我的问题是双重的:

    1. 为什么会这样?
    2. 我该如何预防?
    3. 编辑1: 断言错误回溯也很奇怪;很明显,这些价值观并不相等,但更重要的是价值观在某种程度上是混淆的。 不知怎的,test_a.method_x()== test_c.method_x(),但是test_a.a = / = test_c.a

      method_x类似于:

      def method_x(self):
          if not self.b:
              return {"a": self.a}
          else:
              return {"a": self.a, "b":{"a":self.b.a}}
      

      模型看起来像:

      class Foo(models.Model):
          A_TYPES = (
              ("bar", "Bar"),
              ("baz", "Baz")
          )
          a = models.CharFields(max_length20, choices=A_TYPES)
          b = models.ManyToManyField("self")
          c = models.IntegerField(null=True)
          d = models.BooleanField(default=False)
      

0 个答案:

没有答案