代码之家  ›  专栏  ›  技术社区  ›  Adam Matan

python:对类使用doctests

  •  38
  • Adam Matan  · 技术社区  · 15 年前

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

    如果是这样的话,我应该把doctests放在哪里呢?放在类的docstring上,还是放在构造函数的docstring上?

    为了澄清这一点,我正在寻找:

    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
    

    事先谢谢,

    亚当

    4 回复  |  直到 7 年前
        1
  •  26
  •   Aaron Maenpaa    15 年前

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

    class Test:
        <snip>
    
    if __name__ == "__main__":
        import doctest
        doctest.testmod()
    

    测试地点:

    • 如果它测试整个类,我会把它们放在类的docstring中。
    • 如果它在测试构造函数,我会把它们放在构造函数的docstring中。
    • 如果它在测试一个方法(在本例中似乎是这样),我实际上会把它放在该方法的docstring中。
        2
  •  57
  •   Asclepius    7 年前

    您可以使用 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()})
    
        3
  •  7
  •   Dave Kirby    15 年前

    doctest模块在文件中查找任何docstring并执行其中的任何嵌入代码,因此可以对类使用doctest。

    至于将doctest放在类的docstring或构造函数中是否更好,我认为这取决于您具体记录的内容。

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

    如果docstring专门关于如何创建类的实例,那么它应该进入 __init__ 方法。

    请记住,doctests的目的主要是在文档中具有自验证示例代码,因此imho文档方面应该优先于测试方面。

    编辑:

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

    您需要将此添加到文件结尾:

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

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

    python -m doctest -v test.py
    
        4
  •  0
  •   Jim DeLaHunt    7 年前

    我认为doctest模块文档不能解释如何处理这个问题,它应该在解释该做什么方面做得更好。

    我为测试不需要实例数据,但可能需要访问类数据的类方法而设计的模式是传入类对象而不是实例。

    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()