Подтвердить что ты не робот

Создание и импорт вспомогательных функций в тестах без создания пакетов в тестовой директории с использованием py.test

Вопрос

Как импортировать вспомогательные функции в тестовые файлы без создания пакетов в каталоге 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 не имеет пакетов, а просто тестов, и тесты могут быть запущены в установленной версии пакета, как рекомендуется здесь, в документации py.test о передовом опыте).

4b9b3361

Ответ 1

Мой вариант - создать дополнительный каталог в каталоге tests и добавить его в 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, будьте осторожны, чтобы не конфликтовать с именами.

Ответ 2

В поисках решения этой проблемы я наткнулся на этот вопрос и в итоге принял тот же подход. Создание пакета помощников, манипулирование 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

А затем, в теле функции тестового примера, просто используйте его как

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)

Это довольно просто и документация довольно маленькая. Посмотрите и скажите мне, если это тоже решает вашу проблему.

Ответ 3

Вы можете определить вспомогательный класс в conftest.py, а затем создать приспособление, которое возвращает этот класс (или его экземпляр, в зависимости от того, что вам нужно).

import pytest


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


@pytest.fixture
def helpers():
    return Helpers

Затем в ваших тестах вы можете использовать прибор:

def test_with_help(helpers):
    helpers.help_me()

Ответ 4

Чтобы получить доступ к методу из разных модулей без создания пакетов и использовать эту функцию в качестве вспомогательной функции, я нашел следующее полезное:

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

Ответ 5

Создайте пакет помощников в папке с тестами:

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

в файле setup.cfg:

[pytest]
norecursedirs=tests/helpers

помощники будут доступны с import helpers.

Ответ 6

В качестве другого варианта эта структура каталогов работала для меня:

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

И затем в my_test.py импортируйте утилиты, используя: from test_helpers import utils