【问题标题】:Django unittest result depends on test nameDjango unittest 结果取决于测试名称
【发布时间】:2021-02-24 11:40:28
【问题描述】:

我在测试中预定义了几个字典。 例如。

TIME_DISCOUNT_OFFER = dict(
    time_discount=dict(
        discount_days=5,
        discount_percent=15
        )
    )

这个 dict 进入我的模型(JSONfield),然后在我的测试中,我从中获取数据。当我命名 test test_add_the_rest_of_name django 检测预定义的字典时,但是当我命名 test 时,例如。 test_time_sthdjango 给我输出

    discount = TIME_DISCOUNT_OFFER.get("time_discount").get("discount_percent")
AttributeError: 'NoneType' object has no attribute 'get'

我注意到,在第二种情况下(test_time_sth),根据 django,我的预定义 dict 是空的,无论我是直接从 dict 还是从模型实例获取数据。如果我以不同的方式命名测试,则测试通过。有人知道为什么会这样吗?

小例子:

型号:

from django.contrib.postgres.fields import JSONField

class Offer(models.Model):
    details = JSONField()

测试:

TIME_DISCOUNT_OFFER = dict(
    time_discount=dict(
        discount_days=10,
        discount_percent=25
        )
    )
class OfferTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.offer = Offer.objects.create(details=TIME_DISCOUNT_OFFER)

    def test_special_offer_removed(self):
        self.offer.details.pop('time_discount', None)

    def test_timeframe_offer(self):
        discount = TIME_DISCOUNT_OFFER.get("time_discount").get("discount_percent")

    def test_add_offer(self):
        discount = TIME_DISCOUNT_OFFER.get("time_discount").get("discount_percent")

追溯:

..E
======================================================================
ERROR: test_timeframe_offer (offers.tests.test_offer.OfferTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/admin1/Dokumenty/project/offers/tests/test_offer.py", line 142, in test_timeframe_offer
    discount = TIME_DISCOUNT_OFFER.get("time_discount").get("discount_percent")
AttributeError: 'NoneType' object has no attribute 'get'

----------------------------------------------------------------------
Ran 3 tests in 0.006s

FAILED (errors=1)

【问题讨论】:

  • 请创建一个可重现的最小示例!
  • 添加了最小的可重现示例

标签: python django unit-testing


【解决方案1】:

测试后您没有正确清理。测试中发生变化的所有内容都应在测试结束时进行清理。

在您的特殊情况下,您将在测试 test_special_offer_removed 中删除密钥 time_discount。现在,根据测试的顺序,您可能会在 test_special_offer_removed 之后开始失败的测试,它会找到现在缺少键的字典。

为防止出现此类问题,请确保在每次测试后恢复环境:在 test_special_offer_removed 结束时将 TIME_DISCOUNT_OFFER 恢复到其原始状态!

【讨论】:

  • 感谢您的评论。我仍然不知道,为什么测试test_add_offer 通过,但test_timeframe_offer 失败(无论测试中的顺序是什么),尽管它们是相同的。另外,我尝试不删除 dict 本身,而是更改 cls.offer 实例字段。我应该在 tearDown 中从一开始就定义字典吗?我在测试中做了一些解决方法,所以它通过了,但不知道为什么测试中的名称如此重要
  • 因为它是在test_special_offer_removed 修改字典之前运行的。测试通常按字母顺序运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 2014-07-26
  • 2014-09-14
相关资源
最近更新 更多