Create and import helper functions in tests withou

2020-02-20 06:27发布

Question

How can I import helper functions in test files without creating packages in the test directory?


Context

I'd like to create a test helper function that I can import in several tests. Say, something like this:

# 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)

Using Python 3.5, with py.test 2.8.2


Current "solution"

I'm currently doing this via importing a module inside my project's test directory (which is now a package), but I'd like to do it with some other mechanism if possible (so that my test directory doesn't have packages but just tests, and the tests can be run on an installed version of the package, as is recommended here in the py.test documentation on good practices).

6条回答
闹够了就滚
2楼-- · 2020-02-20 07:07

You could define a helper class in conftest.py, then create a fixture that returns that class (or an instance of it, depending on what you need).

import pytest


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


@pytest.fixture
def helpers():
    return Helpers

Then in your tests, you can use the fixture:

def test_with_help(helpers):
    helpers.help_me()
查看更多
成全新的幸福
3楼-- · 2020-02-20 07:13

my option is to create an extra dir in tests dir and add it to pythonpath in the conftest so.

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

in the conftest.py

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

in setup.cfg

[pytest]
norecursedirs=tests/helpers

this module will be available with import utils, only be careful to name clashing.

查看更多
走好不送
4楼-- · 2020-02-20 07:17

While searching for a solution for this problem I came across this SO question and ended up adopting the same approach. Creating a helpers package, munging sys.path to make it importable and then just importing it...

This did not seem the best approach, so, I created pytest-helpers-namespace. This plugin allows you to register helper functions on your 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

And then, within a test case function body just use it like

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)

Its pretty simple and the documentation pretty small. Take a look and tell me if it addresses your problem too.

查看更多
等我变得足够好
5楼-- · 2020-02-20 07:17

To access a method from different modules without creating packages, and have that function operate as a helper function I found the following helpful:

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")
查看更多
我想做一个坏孩纸
6楼-- · 2020-02-20 07:27

As another option, this directory structure worked for me:

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

And then in my_test.py import the utilities using: from test_helpers import utils

查看更多
forever°为你锁心
7楼-- · 2020-02-20 07:33

Create a helpers package in tests folder:

tests/
    helpers/
      __init__.py
      utils.py
      ...
    # make sure no __init__.py in here!
setup.cfg

in setup.cfg:

[pytest]
norecursedirs=tests/helpers

the helpers will be available with import helpers.

查看更多
登录 后发表回答