Jua*_*oto 35 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)
Run Code Online (Sandbox Code Playgroud)
使用Python 3.5,py.test 2.8.2
当前"解决方案"
我目前正在通过在我的项目test目录(现在是一个包)中导入一个模块来实现这一点,但是如果可能的话我想用其他一些机制来做(因为我的test目录没有包但只是测试,并且可以在已安装的软件包版本上运行测试,如py.test文档中关于良好实践的建议).
sax*_*sax 26
我的选择是在testsdir中创建一个额外的目录并将其添加到conftest中的pythonpath中.
tests/
helpers/
utils.py
...
conftest.py
setup.cfg
Run Code Online (Sandbox Code Playgroud)
在里面 conftest.py
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers'))
Run Code Online (Sandbox Code Playgroud)
在 setup.cfg
[pytest]
norecursedirs=tests/helpers
Run Code Online (Sandbox Code Playgroud)
这个模块将可用import utils,只需要小心命名冲突.
aug*_*rar 17
你可以在conftest.py中定义一个帮助器类,然后创建一个返回该类的fixture(或者它的一个实例,具体取决于你需要的).
import pytest
class Helpers:
@staticmethod
def help_me():
return "no"
@pytest.fixture
def helpers():
return Helpers
Run Code Online (Sandbox Code Playgroud)
然后在测试中,您可以使用夹具:
def test_with_help(helpers):
helpers.help_me()
Run Code Online (Sandbox Code Playgroud)
s0u*_*3ch 15
在寻找这个问题的解决方案时,我遇到了这个问题,并最终采用了相同的方法.创建一个帮助程序包,重新设置sys.path以使其可导入,然后只导入它...
这似乎不是最好的方法,因此,我创建了pytest-helpers-namespace.这个插件允许你在你的注册帮助函数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
Run Code Online (Sandbox Code Playgroud)
然后,在一个测试用例中,函数体就像使用它一样
def test_this():
assert pytest.helpers.my_custom_assert_helper(blah)
def test_this_2():
assert pytest.helpers.assertme(blah)
def test_this_3():
assert pytest.helpers.asserts.me(blah)
Run Code Online (Sandbox Code Playgroud)
它非常简单,文档很小.看一看,告诉我它是否也解决了你的问题.
小智 11
在测试文件夹中创建一个助手包:
tests/
helpers/
__init__.py
utils.py
...
# make sure no __init__.py in here!
setup.cfg
Run Code Online (Sandbox Code Playgroud)
在 setup.cfg 中:
[pytest]
norecursedirs=tests/helpers
Run Code Online (Sandbox Code Playgroud)
助手将可用import helpers。
小智 7
要从不同模块访问方法而不创建包,并让该函数作为辅助函数运行,我发现以下帮助:
conftest.py:
@pytest.fixture
def compare_test_vs_actual():
def a_function(test, actual):
print(test, actual)
return a_function
Run Code Online (Sandbox Code Playgroud)
test_file.py:
def test_service_command_add(compare_test_vs_actual):
compare_test_vs_actual("hello", "world")
Run Code Online (Sandbox Code Playgroud)
你们中的一些人可能会完全支持我的建议。然而,使用其他模块的通用函数或值的非常简单的方法是将其直接注入到通用工作区中。示例:
conftest.py:
import sys
def my_function():
return 'my_function() called'
sys.modules['pytest'].common_funct = my_function
Run Code Online (Sandbox Code Playgroud)
测试我.py
import pytest
def test_A():
print(pytest.common_funct())
Run Code Online (Sandbox Code Playgroud)
小智 6
对于 pytest 7(至少),完成此操作的最简单方法是将以下配置添加到 pytest.ini 或 pyproject.toml 中。这会将tests目录添加到您的目录中sys.path并使相应的模块可用:
pythonpath = ["tests"]
Run Code Online (Sandbox Code Playgroud)
也许将测试助手与测试分开会更好,但这是一个风格问题。
例如,使用单独的目录,并使用它,pyproject.toml它看起来像这样:
[tool.pytest.ini_options]
pythonpath = ["test_helpers"]
testpaths = ["tests"]
addopts = [
"--import-mode=importlib",
]
Run Code Online (Sandbox Code Playgroud)
src/
...
tests/
...
test_helpers/
...
Run Code Online (Sandbox Code Playgroud)
这配置了importlib 此处推荐的导入模式,其设计正是为了防止修改 sys.path,但是,如果您小心命名并且需要提取常见的测试助手,这可能是一个可行的选择。
| 归档时间: |
|
| 查看次数: |
11467 次 |
| 最近记录: |