gpt4 book ai didi

python - 导入模块前的 nose-doctest 模块夹具

转载 作者:太空狗 更新时间:2023-10-30 01:22:03 26 4
gpt4 key购买 nike

我用nose做测试采集,也想用它的doctest插件。我有一个模块需要固定装置才能导入。因此,我不能使用 nose 的模块固定装置,因为它们是从被测模块加载的。有没有办法在模块外为 nose-doctest 指定模块固定装置?

对于某些用例,一个选项是检测是否在 doctest 下运行并在模块开头应用夹具。我也有兴趣听到这个用例的答案。

但是,在某些情况下这是行不通的:当导入由于 SyntaxError 而失败时,任何模块代码都不会运行。就我而言,我主要开发与 python 2 和 python 3 兼容的代码(没有 2to3)。然而,有一些特定于 python 3 的模块,当在 python 2 下运行时,根本不应该用 Nose 检查它们。我最好的选择是什么?

编辑:MWE(针对 SyntaxError 情况)

我有一个包含许多小模块的包,其中一些使用 python 3 语法。这是包结构:

~/pckg/
__init__.py
py3only.py
... (other modules)
tests/
test_py3only.py

有些测试写成unittest.TestCase,但我也想测试文档字符串中的代码示例。 ~/pckg/__init__.py 是空的。

~/pckg/py3only.py:

def fancy_py3_func(a:"A function argument annotation (python 3 only syntax)"):
""" A function using fancy syntax doubling it's input.

>>> fancy_py3_func(4)
8
"""
return a*2

~/pckg/tests/test_py3only.py:

import sys, unittest

def setup_module():
if sys.version_info[0] < 3:
raise unittest.SkipTest("py3only unavailable on python "+sys.version)

class TestFancyFunc(unittest.TestCase):
def test_bruteforce(self):
from pckg.py3only import fancy_py3_func
for k in range(10):
self.assertEqual(fancy_py3_func(k),2*k)

在 python 3 上测试,所有内容都经过测试并通过(从封闭文件夹运行,例如 ~):

~ nosetests3 -v --with-doctest pckg
Doctest: pckg.py3only.fancy_py3_func ... ok
test_bruteforce (test_py3only.TestFancyFunc) ... ok

在 python 2 上,~/pckg/tests/test_py2only.py 的模块 fixture 正确检测到情况并跳过测试。但是,我们从 ~/pckg/py3only.py 得到一个 SyntaxError:

~ nosetests -v --with-doctest pckg 
Failure: SyntaxError (invalid syntax (py3only.py, line 1)) ... ERROR
SKIP: py3only unavailable on python 2.7.6 (default, Mar 22 2014, 22:59:56)

类似于 ~/pckg/tests/test_py3only.py:setup_module() 的函数可以解决这个问题,如果我能让 nose 在它运行之前运行该代码doctest 插件甚至尝试导入该模块。

看来我最好的选择是编写一个适当的顶级测试脚本来处理测试的集合...

最佳答案

可以使用 nose-exclude 排除特定的测试文件、目录、类或方法 Nose 插件。它有 --exclude-* 选项。

要处理丢失的模块,您必须使用 mock 修补 sys.modules

F.e,mycalc 模块中有一个 Calc 类,但我无法访问它,因为它丢失了。还有两个模块,mysuper_calcmysuper_calc3,后者是 Python 3 特定的。这两个模块导入 mycalcmysuper_calc3 不应该在 Python 2 下进行测试。如何在模块外对它们进行 doctest,这是在纯文本文件中?我认为这是OP的情况。

计算/mysuper_calc3.py

from sys import version_info
if version_info[0] != 3:
raise Exception('Python 3 required')
from mycalc import Calc
class SuperCalc(Calc):
'''This class implements an enhanced calculator
'''
def __init__(self):
Calc.__init__(self)

def add(self, n, m):
return Calc.add(self, n, m)

计算/mysuper_calc.py

from mycalc import Calc

class SuperCalc(Calc):
'''This class implements an enhanced calculator
'''
def __init__(self):
Calc.__init__(self)

def add(self, n, m):
return Calc.add(self, n, m)

现在模拟mycalc

>>> from mock import Mock, patch
>>> mock = Mock(name='mycalc')

模块 mycalc 有类 Calc,它有方法 add。我用 2+3 测试 SuperCalc 实例 add 方法。

>>> mock.Calc.add.return_value = 5  

现在可以在 with block 中有条件地导入补丁 sys.modulesmysuper_calc3

>>> with patch.dict('sys.modules',{'mycalc': mock}):
... from mysuper_calc import SuperCalc
... if version_info[0] == 3:
... from mysuper_calc3 import SuperCalc

计算/doctest/mysuper_calc_doctest.txt

>>> from sys import version_info
>>> from mock import Mock, patch
>>> mock = Mock(name='mycalc')
>>> mock.Calc.add.return_value = 5

>>> with patch.dict('sys.modules',{'mycalc': mock}):
... from mysuper_calc import SuperCalc
... if version_info[0] == 3:
... from mysuper_calc3 import SuperCalc
>>> c = SuperCalc()
>>> c.add(2,3)
5

文件 mysuper_calc_doctest.txt 必须在其自己的目录中单独存在,否则 nosetests 在非测试模块中搜索 doctest

PYTHONPATH=.. nosetests --with-doctest --doctest-extension=txt --verbosity=3

Doctest:mysuper_calc_doctest.txt ... 好


在 0.038 秒内运行 1 个测试

好的

围绕 nosetests 的包装器,用于检测 Python 3,它将没有语法错误的 .py 文件传递​​给 nosetests

mynosetests.py

import sys
from subprocess import Popen, PIPE
from glob import glob

f_list = []

py_files = glob('*py')
try:
py_files.remove(sys.argv[0])
except ValueError:
pass

for py_file in py_files:
try:
exec open(py_file)
except SyntaxError:
continue
else:
f_list.append(py_file)

proc = Popen(['nosetests'] + sys.argv[1:] + f_list,stdout=PIPE, stderr=PIPE)
print('%s\n%s' % proc.communicate())
sys.exit(proc.returncode)

关于python - 导入模块前的 nose-doctest 模块夹具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26440574/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com