繁体   English   中英

如何让 py.test 或 nose 在所有 python 文件中寻找测试?

[英]How to make py.test or nose to look for tests inside all python files?

我确实有几个小模块,其中测试在其中, py.testnose不查找它们,因为它们的文件名中不包含test

我如何说服py.testnose递归地在所有 python 文件中查找测试 - '''包括文件名中没有test的文件'''?

在源文件中,我确实保留了标准命名约定: class testSomeName和方法def test_some_name

如果这不可能,我可以使用什么其他解决方案来获得相同的结果。

我不想手动创建包含测试的所有文件的列表,我想要一个支持发现的解决方案。

使用py.test它很简单。 使用此内容创建conftest.py文件:

# content of conftest.py file at root of your project
def pytest_collect_file(path, parent):
    if path.ext == ".py":
        return parent.Module(path, parent)

这将扩展收集过程,为每个“.py”文件创建一个测试“模块”节点。 将它放入conftest.py文件使其成为特定于项目的扩展,如果您键入以下内容,则会自动加载:

py.test 

出于提供信息的目的,您还可以键入:

py.test --collectonly

查看收集的测试和文件,示例输出:

<Directory 'morecollect'>
   <Module 'conftest.py'>
   <Directory 'pkg'>
     <Module 'test_x.py'>
        <Function 'test_hello2'>
   <Module 'x.py'>   # this is collected because of our conftest.py extension
     <Function 'test_hello'>

如果需要,您还可以将上述conftest.py文件打包为可安装的插件,并通过安装插件使扩展可用。 在这种情况下,您根本不需要任何conftest.py文件。

在项目的根目录下放置一个“setup.cfg”文件,它包含以下两行:

[pytest]
python_files=*.py

然后py.test从所有*.py文件中选择测试。 在这里解释: pytest docs

与鼻子:

nosetests --all-modules

您还可以查看Nose ,它将发现测试而无需使用固定的文件名约定。

您可以使用以下代码绕过用于过滤nose中文件的正则表达式。 创建一个python模块(即my_nosetests.py

import nose
from nose.plugins.base import Plugin

class ExtensionPlugin(Plugin):

    name = "ExtensionPlugin"

    def options(self, parser, env):
        Plugin.options(self,parser,env)

    def configure(self, options, config):
        Plugin.configure(self, options, config)
        self.enabled = True

    def wantFile(self, file):
        return file.endswith('.py')

    def wantDirectory(self,directory):
        return True

    def wantModule(self,file):
        return True


if __name__ == '__main__':
    includeDirs = ["-w", ".", ".."]
    nose.main(addplugins=[ExtensionPlugin()], argv=sys.argv.extend(includeDirs))

现在运行my_nosetests.py就像运行nosetests ,你应该运行你的测试。 请注意,您实际上正在加载所有模块并在其中搜索测试。 注意模块加载的任何副作用。

文档说明了这一点

默认情况下,遍历所有不以点开头的目录,查找test _ *。py和* _test.py文件。 这些Python文件是在其包名下导入的。

你能确保你的代码是这种情况吗?

更新

(Caveat Emptor:我没有尝试/测试过这个)如何使用提供的钩子来收集目录和文件?

py.test调用以下两个用于收集文件和目录的基本钩子:

def pytest_collect_directory(path, parent):
    """ return Collection node or None for the given path. """

def pytest_collect_file(path, parent):
    """ return Collection node or None for the given path. """

两者都返回给定路径的集合节点 来自所有钩子实现的所有返回节点都将参与收集和运行协议。 parent对象是父节点,可用于通过parent.config对象访问命令行选项。

对于 pytest-6,我必须更改 @hpk42 答案以直接返回给定源/测试代码布局的 Module 实例。 原始答案针对 pytest 这个主要版本提出了一个例外,因为 API 同时发生了变化。

def pytest_collect_file(path, parent):
    """Look in all Python files for test cases."""
    from _pytest.python import Module

    if path.ext == ".py":
        return Module.from_parent(parent, fspath=path)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM