pythondoctest中的对象重用
我有一个像这样的医生测试样本pythondoctest中的对象重用,python,unit-testing,doctest,Python,Unit Testing,Doctest,我有一个像这样的医生测试样本 """ 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 iniFileGener
"""
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
您可以使用testmod(extraglobs={'f':initFileGenerator(“”)})
全局定义可重用对象
正如《圣经》所说
extraglobs提供了一个dict,该dict合并到用于执行示例的globals中。这与dict.update()类似
但我过去总是在所有方法之前测试类的\uuuu doc\uu
中的所有方法
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'
要获得所有测试都使用共享执行上下文(即可以共享和重用结果的单个测试)的可读模块,必须查看的相关部分如下: 。。。每次
doctest
找到要测试的文档字符串时,它都会使用M
的全局文件的一个浅副本,这样运行测试不会改变模块的真实全局文件,并且M
中的一个测试不会留下碎屑,意外地允许另一个测试工作
您可以通过将globs=your_dict
传递到testmod()
或testfile()
来强制使用您自己的dict作为执行上下文
鉴于此,在doctest
模块中,除了使用copies(即dict
的copy()
方法)外,它还可以在每次测试后清除全局dict(使用clear()
)
因此,您可以使用以下内容修补自己的globals字典:
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()))
对于任何像我这样发现这个的人,这里有一个简单的破解方法来解决这个问题 在模块文档中,将“全局”值作为
内置模块的属性附加,例如
“”“
我的模块文档
>>>进口内置设备
>>>builtins.sample\u value=“这是一个长值”
>>>builtins.sample_func=lambda x:x.lower()
"""
内置
模块会自动导入到每个作用域中,因此其属性将在您的函数中可用,包括doctest函数
def first\u char\u func(s:str)->str:
"""
返回函数的第一个字符
>>>第一个字符函数(样本函数(样本值))
H
"""
如果len(s)>0,则返回s[0],否则无
然而,可以说,一旦你达到了这个阶段,你最好只写一个单元测试。就在我之前,是的,在extraglobs上。虽然我不喜欢extraglobs方法,但我不太喜欢这个答案——doctests的一些要点是记录方法,你在这里丢失了这些方法。@Thomas在我检查了一些流行的和有良好文档记录的项目的源代码后,我认为这没问题,很酷——我只是喜欢在DocString中看到它,这样我就可以调用help()在方法上查看它是如何工作的,而不是滚动类文档。
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()))