python - Python 中的单元测试对象 - 对象未在设置中覆盖

标签 python unit-testing unittest2

我正在使用 unittest 在 Python 中对类进行单元测试。据我了解, unittest 在每次测试之前调用 setUp 函数,以便单元测试对象的状态相同并且测试执行的顺序无关紧要.

现在我正在测试这个类...

#! usr/bin/python2

class SpamTest(object):

    def __init__(self, numlist = []):
        self.__numlist = numlist

    @property
    def numlist(self):
        return self.__numlist

    @numlist.setter
    def numlist(self, numlist):
        self.__numlist = numlist

    def add_num(self, num):
        self.__numlist.append(num)

    def incr(self, delta):
        self.numlist = map(lambda x: x + 1, self.numlist)

    def __eq__(self, st2):
        i = 0
        limit = len(self.numlist)

        if limit != len(st2.numlist):
            return False

        while i < limit:
            if self.numlist[i] != st2.numlist[i]:
                return False

            i += 1

        return True

通过以下单元测试...

#! usr/bin/python2

from test import SpamTest

import unittest

class Spammer(unittest.TestCase):

    def setUp(self):
        self.st = SpamTest()
        #self.st.numlist = [] <--TAKE NOTE OF ME!
        self.st.add_num(1)
        self.st.add_num(2)
        self.st.add_num(3)
        self.st.add_num(4)

    def test_translate(self):
        eggs = SpamTest([2, 3, 4, 5])
        self.st.incr(1)
        self.assertTrue(self.st.__eq__(eggs))

    def test_set(self):
        nl = [1, 4, 1, 5, 9]
        self.st.numlist = nl
        self.assertEqual(self.st.numlist, nl)

if __name__ == "__main__":
    tests = unittest.TestLoader().loadTestsFromTestCase(Spammer)
    unittest.TextTestRunner(verbosity = 2).run(tests)

此测试对 test_translate 失败。

我可以做两件事来使测试成功:

(1) 取消注释 setUp 函数中的第二行。或者,

(2) 更改测试名称,使 translate 先出现。我注意到 unittest 按字母顺序执行测试。将 translate 更改为例如 atranslate 以便它首先执行,这样所有测试都会成功。

对于 (1),我无法想象这会如何影响测试,因为在 setUp 的第一行,我们为 self.st 创建了一个新对象。至于 (2),我的提示是相似的,因为,嘿,在 setUp 上,我将一个新对象分配给 self.st 所以无论我对 self.st 做什么test_set 中的 不应影响 test_translate 的结果。

那么,我在这里缺少什么?

最佳答案

在不研究解决方案的细节的情况下,您应该阅读 Default Parameter Values in Python弗雷德里克·伦德 (Fredrik Lundh) 着。

它很可能用您的空列表 作为默认参数来解释您的问题。原因是该列表仅在第一次为空,除非您稍后明确将其设为空。初始为空的默认列表是列表类型的单个实例,在未传递显式参数时被重用。

最好阅读上面的文章来修正您对默认参数的想法。原因是合乎逻辑的,但可能出乎意料。

通常推荐的修复方法是使用 None 作为 __init__ 的默认值,如果没有传递参数,则在主体内设置空列表,如下所示:

class SpamTest(object):

    def __init__(self, numlist=None):
        if numlist is None:
            numlist = []         # this is the new instance -- the empty list
        self.__numlist = numlist

关于python - Python 中的单元测试对象 - 对象未在设置中覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11381968/

相关文章:

pythonunittest2assertAlmostEqual 与 `places` 工作不正确

R Markdown 中的Python

python - 在数字表示形式cpp和python之间转换

python - Z3:如何在 Z3 python 中编码 If-the-else?

java - 我可以使用 @MockBean 在我的测试类的一种方法中模拟 bean 吗?

java - Spring Boot @Autowired 在单元测试中返回 NullPointerException

python - 如何计算 Pyspark 中 None 或 NaN 值的百分比?

c# - NUnit - 如何测试实现特定接口(interface)的所有类

来自脚本的 python Nose ,从文件中收集测试类,然后运行测试

django - 在 Django 中对执行外部服务调用的 View 进行单元测试时,什么是好的做法