7

我有一个像这样的示例文档测试。

"""
This is the "iniFileGenerator" module.
>>> hintFile = "./tests/unit_test_files/hint.txt"
>>> f = iniFileGenerator(hintFile)
>>> print f.hintFilePath
./tests/unit_test_files/hint.txt
"""
class iniFileGenerator:
    def __init__(self, hintFilePath):
        self.hintFilePath = hintFilePath
    def hello(self):
        """
        >>> f.hello()
        hello
        """
        print "hello"
if __name__ == "__main__":
    import doctest
    doctest.testmod()

当我执行这段代码时,我得到了这个错误。

Failed example:
    f.hello()
Exception raised:
    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1254, in __run
        compileflags, 1) in test.globs
      File "<doctest __main__.iniFileGenerator.hello[0]>", line 1, in <module>
        f.hello()
    NameError: name 'f' is not defined

此错误是由访问测试hello()方法时无法访问的“f”引起的。

有什么方法可以共享之前创建的对象吗?没有它,就需要在必要时始终创建对象。

def hello(self):
    """
    hintFile = "./tests/unit_test_files/hint.txt"
    >>> f = iniFileGenerator(hintFile)
    >>> f.hello()
    hello
    """
    print "hello"
4

3 回答 3

6

您可以使用testmod(extraglobs={'f': initFileGenerator('')})全局定义可重用对象。

正如doctest 文档所说,

extraglobs给出了一个 dict 合并到用于执行示例的全局变量中。这就像 dict.update()

但是我曾经在所有方法__doc__之前测试类中的所有方法。

class MyClass(object):
    """MyClass
    >>> m = MyClass()
    >>> m.hello()
    hello
    >>> m.world()
    world
    """

    def hello(self):
        """method hello"""
        print 'hello'

    def world(self):
        """method world"""
        print 'world'
于 2012-10-28T06:08:54.150 回答
2

要获得具有所有使用共享执行上下文的测试的识字模块(即可以共享和重用结果的单个测试),必须查看有关执行上下文的文档的相关部分,其中说:

...每次doctest找到要测试的文档字符串时,它都会使用 's 全局变量的浅表 副本M因此运行测试不会更改模块的真实全局变量,因此一个测试M不会留下意外允许另一个测试的碎屑测试工作。

...

您可以通过传递给或代替来强制使用自己的dict作为执行上下文。globs=your_dicttestmod()testfile()

鉴于此,我设法doctest模块进行逆向工程,除了使用副本(即dict'copy()方法)外,它还clear()在每次测试后清除全局字典(使用 )。

因此,可以使用以下内容修补自己的全局字典:

class Context(dict):
    def clear(self):
        pass
    def copy(self):
        return self 

然后将其用作:

import doctest
from importlib import import_module

module = import_module('some.module')
doctest.testmod(module,
                # Make a copy of globals so tests in this
                # module don't affect the tests in another
                glob=Context(module.__dict__.copy()))
于 2016-02-06T14:59:37.040 回答
1

对于像我这样发现这个问题的人,这里有一个简单的技巧可以解决这个问题。

在您的模块文档中,将“全局”值作为builtins模块的属性附加,例如

"""
My module documentation

>>> import builtins
>>> builtins.sample_value = "Here is a long value"
>>> builtins.sample_func = lambda x: x.lower()
"""

builtins模块会自动导入每个范围,因此它的属性将在您的函数中可用,包括 doctest 函数

def first_char_func(s: str) -> str:
   """
   Returns the first char of a function

   >>> first_char_func(sample_func(sample_value))
   h
   """  
   return s[0] if len(s) > 0 else None

然而,可以说,一旦你到了这个阶段,你最好只写一个单元测试。

于 2019-05-10T11:09:03.780 回答