在测试中创建和导入辅助函数,而无需使用py.test在测试目录中创建包

时间:2015-11-03 20:04:09

标签: python unit-testing pytest

问题

如何在不在test目录中创建包的情况下导入测试文件中的辅助函数?


上下文

我想创建一个测试辅助函数,我可以在几个测试中导入它。说,像这样:

# In common_file.py

def assert_a_general_property_between(x, y):
    # test a specific relationship between x and y
    assert ...


# In test/my_test.py

def test_something_with(x):
    some_value = some_function_of_(x)
    assert_a_general_property_between(x, some_value)

使用Python 3.5,py.test 2.8.2


当前"解决方案"

我目前正在通过在我的项目test目录(现在是一个包)中导入一个模块来实现这一点,但是我想用其他一些机制来做如果可能的话(以便我的test目录没有包但只是测试,并且测试可以在已安装的软件包版本上运行,如建议here in the py.test documentation on good practices)。

7 个答案:

答案 0 :(得分:24)

我的选择是在tests目录中创建一个额外的目录,并将其添加到conftest中的pythonpath中。

tests/
    helpers/
      utils.py
      ...
    conftest.py
setup.cfg
conftest.py

中的

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers'))
setup.cfg

中的

[pytest]
norecursedirs=tests/helpers

此模块将与import utils一起使用,只需注意命名冲突。

答案 1 :(得分:15)

在寻找这个问题的解决方案时,我遇到了这个问题并最终采用了相同的方法。创建一个帮助程序包,重新设置int i = 0; auto f = [=,&i]() { i = 1; }; 以使其可导入,然后只导入它......

这似乎不是最佳方法,因此,我创建了pytest-helpers-namespace。这个插件允许您在sys.path上注册帮助函数:

conftest.py

然后,在测试用例函数体中,只需使用它就像

import pytest

pytest_plugins = ['helpers_namespace']

@pytest.helpers.register
def my_custom_assert_helper(blah):
    assert blah

# One can even specify a custom name for the helper
@pytest.helpers.register(name='assertme')
def my_custom_assert_helper_2(blah):
    assert blah

# And even namespace helpers
@pytest.helpers.asserts.register(name='me')
def my_custom_assert_helper_3(blah):
    assert blah

它非常简单,文档很小。看一看,告诉我它是否也解决了你的问题。

答案 2 :(得分:11)

您可以在conftest.py中定义一个帮助器类,然后创建一个返回该类的fixture(或者它的一个实例,具体取决于您的需要)。

import pytest


class Helpers:
    @staticmethod
    def help_me():
        return "no"


@pytest.fixture
def helpers():
    return Helpers

然后在测试中,您可以使用夹具:

def test_with_help(helpers):
    helpers.help_me()

答案 3 :(得分:3)

要从不同模块访问方法而不创建包,并使该功能作为辅助功能运行,我发现以下帮助:

conftest.py:

@pytest.fixture
def compare_test_vs_actual():
    def a_function(test, actual):
        print(test, actual)
    return a_function

test_file.py:

def test_service_command_add(compare_test_vs_actual):
    compare_test_vs_actual("hello", "world")

答案 4 :(得分:2)

我的建议很可能会使你们中的某些人完全坚持。但是,使用来自其他模块的通用功能或值的非常简单的方法是将其直接注入到通用工作空间中。示例:
conftest.py:

import sys

def my_function():
   return 'my_function() called'

sys.modules['pytest'].common_funct = my_function

test_me.py

import pytest

def test_A():
   print(pytest.common_funct())

答案 5 :(得分:1)

在tests文件夹中创建一个帮助程序包: tests/ helpers/ __init__.py utils.py ... # make sure no __init__.py in here! setup.cfg

setup.cfg中的

[pytest] norecursedirs=tests/helpers

帮助者可以使用import helpers

答案 6 :(得分:-1)

作为另一种选择,这个目录结构对我有用:

mypkg/
    ...
test_helpers/
    __init__.py
    utils.py  
    ...
tests/
    my_test.py
    ...

然后在my_test.py中导入实用程序: from test_helpers import utils