【问题标题】:Python: using doctests for classesPython:对类使用文档测试
【发布时间】:2011-02-12 02:01:56
【问题描述】:

是否可以将 Python 的 doctest 概念用于类,而不仅仅是函数?

如果是这样,我应该将文档测试放在哪里 - 在类的文档字符串中,还是在构造函数的文档字符串中?

为了澄清,我正在寻找类似的东西:

class Test:
    """
    >>> a=Test(5)
    >>> a.multiply_by_2()
    10
    """
    def __init__(self, number):
        self._number=number

    def multiply_by_2(self):
        return self._number*2

提前致谢,

亚当

【问题讨论】:

  • 附带说明,始终从object 继承而不是什么都没有,这样您就可以使用新式类
  • 除了在python 3中,只有新式类,object是隐含的,没有声明的父母。

标签: python unit-testing doctest


【解决方案1】:

doctest 模块在文件中查找任何文档字符串并执行其中的任何嵌入代码,因此可以将 doctest 用于类。

至于将文档测试放在类的文档字符串还是构造函数中更好,我认为这取决于您具体记录的内容。

如果文档字符串给出了类的一般概述以及如何使用它,那么我认为最好将它放在类中。

如果文档字符串专门关于如何创建类的实例,那么它应该放在__init__ 方法中。

请记住,doctests 的目的主要是在文档中包含自我验证的示例代码,因此恕我直言,文档方面应优先于测试方面。

编辑:

在上面的示例中,没有执行 doctest 的代码 - 运行 python test.py -v 将执行只定义类的主要 python 代码。

您需要将其添加到文件末尾:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

或者,如果您使用的是 Python 2.6 或更高版本,请使用以下命令运行它:

python -m doctest -v test.py

【讨论】:

  • 谢谢,但为什么我的示例不起作用?我试过python test.py -v,一无所获
  • @Adam 如果您发布的是完整的test.py 文件,那么您没有发布if __name__ == "__main__": import doctest; doctest.testmod();如果您确实使用了它,则没有输出意味着没有错误。 :)
【解决方案2】:

您在文件底部缺少实际运行 doctest 的代码:

class Test:
    <snip>

if __name__ == "__main__":
    import doctest
    doctest.testmod()

至于把测试放在哪里:

  • 如果它是作为一个整体来测试班级,我会将它们放在班级的文档字符串中。
  • 如果是测试构造函数,我会把它们放在构造函数的文档字符串中。
  • 如果它正在测试一种方法(在这种情况下似乎是这样),我实际上会将它们放在该方法的文档字符串中。

【讨论】:

  • +1 谢谢!然而,记录一个方法似乎有点乏味,因为它需要我为每个 doctest 初始化一个对象。
  • @Adam:如果您需要更复杂的测试,请使用 unittest 模块。 doctest 主要用于测试文档,而不是测试代码。
【解决方案3】:

您可以使用 extraglobs 参数,而不是在每个方法中实例化对象:

class Test:
    def multiply_by_2(self):
        """
        >>> t.multiply_by_2()
        10
        """
        return self._number*2

if __name__ == '__main__':
    import doctest
    doctest.testmod(extraglobs={'t': Test()})

【讨论】:

    【解决方案4】:

    我认为 doctest 模块文档没有解释如何处理这个问题,它应该更好地解释要做什么。

    我发现用于测试不需要实例数据但可能需要访问类数据的类方法的模式是传入 Class 对象而不是实例。

    class Test:
        """
        >>> Test.multiply_by_3(Test,2)
        6
        """
        def __init__(self, number):
            self._number=number
    
        _THREE = 3
        def multiply_by_3(self, x):
            return x*self._THREE
    
    if __name__ == "__main__":
        import doctest
        doctest.testmod()
    

    【讨论】:

      猜你喜欢
      • 2013-09-27
      • 2013-05-27
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多