Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 导入模块前,测试模块夹具_Python_Testing_Nose_Doctest - Fatal编程技术网

Python 导入模块前,测试模块夹具

Python 导入模块前,测试模块夹具,python,testing,nose,doctest,Python,Testing,Nose,Doctest,我使用nose进行测试收集,我还想使用它的doctest插件。我有一个模块需要一个夹具才能导入。因此,我不能使用nose的模块夹具,因为它们是从测试模块加载的。有没有办法为模块外的nose doctest指定模块固定装置 对于某些用例,一个选项是检测是否在doctest下运行,并在模块的开头应用fixture。我也想听听这个用例的答案 但是,在某些情况下,这无法工作:当导入由于语法错误而失败时,不会运行任何模块代码。在我的例子中,我主要是开发与Python2和Python3兼容的代码(没有2to

我使用nose进行测试收集,我还想使用它的doctest插件。我有一个模块需要一个夹具才能导入。因此,我不能使用nose的模块夹具,因为它们是从测试模块加载的。有没有办法为模块外的nose doctest指定模块固定装置

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

但是,在某些情况下,这无法工作:当导入由于
语法错误而失败时,不会运行任何模块代码。在我的例子中,我主要是开发与Python2和Python3兼容的代码(没有
2to3
)。然而,在Python2下运行时,有一些特定于Python3的模块根本不应该通过nose进行检查。我最好的选择是什么

编辑:MWE(针对
语法错误
情况)

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

~/pckg/
  __init__.py
  py3only.py
  ... (other modules)
  tests/
    test_py3only.py
有些测试是以
unittest.TestCase
的形式编写的,但我也希望测试docstrings中的代码示例<代码>~/pckg/\uuuuu init\uuuuu.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
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)
~/pckg/tests/test_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
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)
在Python2上,
~/pckg/tests/test\u py2only.py
的模块fixture正确地检测到情况并跳过测试。但是,我们从
~/pckg/py3only.py
中得到一个
语法错误:

~ 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\u py3only.py:setup\u module()
的函数可以解决这个问题,如果我能让
nose
在doctest插件尝试导入该模块之前运行该代码


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

Nose有以下选项:

  --doctest-fixtures=SUFFIX
                    Find fixtures for a doctest file in module with this
                    name appended to the base name of the doctest file

也许您可以将装置隔离到一个单独的文件?

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

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

>>> mock.Calc.add.return_value = 5  
例如,在
mycalc
模块中有一个
Calc
类,但我无法访问它,因为它丢失了。还有另外两个模块,
mysuper\u calc
mysuper\u calc3
,后者是特定于Python 3的。这两个模块导入的
mycalc
mysuper\u calc3
不应在Python 2下测试。如何在纯文本文件中的模块外对它们进行doctest?我想这是OP的情况

计算/mysuper\u计算3.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)
计算/我的上级计算

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  
现在,补丁
sys.modules
mysuper\u calc3
可以有条件地导入到
with
块中

>>> with patch.dict('sys.modules',{'mycalc': mock}):
...     from mysuper_calc import SuperCalc
...     if version_info[0] == 3:
...         from mysuper_calc3 import SuperCalc
calc/doctest/mysuper\u calc\u 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\u calc\u doctest.txt
必须单独位于其自己的目录中,否则
nosetests
将在非测试模块中搜索
doctest

PYTHONPATH=.. nosetests --with-doctest --doctest-extension=txt --verbosity=3
Doctest:mysuper\u calc\u Doctest.txt。。。嗯


在0.038秒内运行1次测试

围绕
nosetests
的包装器,用于检测Python3,它将.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)

在没有X或Y气味的情况下无法导入模块,这意味着,例如,
pydoc
pylint
都不能用于您的代码。在导入时更改模块,因为它正在测试中,这会破坏整个测试点,不是吗?我基本上有两种情况:缺少可选的外部依赖项,以及使用新的python 3语法的模块,在python 2下测试。在这两种情况下,测试基本上是徒劳的,模块不可用。我想抑制测试失败,并可能用消息替换它们,即库的某些部分由于缺少依赖项而不可用。
nosetests-v——使用doctest pckg
可以让Python 2看到Python 3代码,因为您可以从顶部目录运行
——使用doctest
。从
tests
文件夹运行unittest和doctest测试。为了使doctest能够像我所做的那样成功地将其提取到纯文本文件中,以便您可以有条件地导入。>类似于~/pckg/tests/test\u py3only.py:setup\u module()的函数可以解决该问题<代码>设置
函数用于单元测试。我不想将doctest提取到文本文件中:它们构成docstring的一部分。我想测试它们以确保它们是正确的<代码>设置
函数构成所谓的
装置的一部分,我希望有一种方法可以为docstring嵌入式doctest指定它们。我想这是徒劳的。听起来很有趣,重要的问题是在导入模块之前是否运行夹具。我来试一试。不幸的是,
--doctestfixtures
只考虑非模块doctest。因此,当doctest搜索模块进行测试时,这不能帮助我在导入过程中隐藏SyntaxError
s。无论如何,感谢您的回答!当然,用模拟模块修补
sys.modules
,将是我的设备可以做的一个可能的操作,以使它们可导入。问题是,我应该把这个fixture代码放在哪里,这样
nose
nose doctest
尝试导入模块之前运行它?同时,
nose exclude
允许我从测试中排除使用python 3语法的文件,它只允许从
node.cfg
文件或命令行静态执行此操作。我更愿意去巴黎