2015-11-03 30 views
24

PytanieTworzenie i import pomocnika funkcje w testach bez tworzenia pakietów w katalogu testów przy użyciu py.test

Jak mogę zaimportować funkcji pomocniczych w plikach testowych bez tworzenia pakietów w katalogu test?


Kontekst

Chciałbym utworzyć funkcję testu pomocnika, który można importować w kilku testach. Powiedzieć coś takiego:

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

Korzystanie Python 3.5, z py.test 2.8.2


Obecny "rozwiązanie"

Jestem obecnie robi to poprzez importowanie modułu do katalogu mojego projektu test (który jest teraz pakietem), ale chciałbym to zrobić z innym mechanizmem, jeśli to możliwe (mój katalog test nie ma pakietów, ale tylko testy, a testy można uruchomić na zainstalowanej wersji pakietu, zgodnie z zaleceniami here in the py.test documentation on good practices).

+1

Wydaje się być szalonym, że pytest zniechęca '__init __. Py'-files, ale jednocześnie nie zapewnia alternatywy dla dzielenia się funkcjami pomocniczymi między testami. Moje włosy stają się szare. – qff

Odpowiedz

18

Moja opcja to stworzenie dodatkowego katalogu w katalogu tests i dodanie go do pythonpath w konfigurze.

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

w conftest.py

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

w setup.cfg

[pytest] 
norecursedirs=tests/helpers 

moduł ten będzie dostępny z `utils importu, tylko uważać, aby nazwa zderzeniu.

+1

Naprawdę podobało mi się to rozwiązanie, szczególnie dlatego, że zachowuje konfigurację ścieżki importu kodu za pomocą testów ", co dla mnie oznacza prostszy projekt. Dzięki! –

+1

Myślę, że 'norecursdirs = tests/utils' powinno być' norecursedirs = tests/helperów' (zauważ, że dodanie e w recurse). Czy to jest poprawne? –

+0

@ Eliza masz rację. po prostu zaktualizuj moją odpowiedź. – sax

9

Szukając rozwiązania tego problemu natknąłem się na to pytanie SO i zakończyłem przyjmowanie tego samego podejścia. Tworzenie pakietu pomocy, mungowanie sys.path, aby można go było zaimportować, a następnie po prostu zaimportować ...

To nie wydaje się być najlepszym rozwiązaniem, dlatego stworzyłem pytest-helpers-namespace. Wtyczka ta pozwala zarejestrować funkcji pomocniczych na swojej 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 

A potem, w ciele funkcji przypadków testowych po prostu użyj go jak

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) 

jest dość proste i dokumentacja dość małe. Spójrz i powiedz mi, czy to rozwiązuje twój problem.

+0

Fajnie, popatrzę. Dzięki! –

+0

Próbowałem tego, jednak zawsze otrzymuję komunikat "RuntimeError: Wywoływany pomocnik nie był zarejestrowany". –

+0

Czy możesz złożyć zgłoszenie na wtyczkę z przykładem, jak wyzwolić swój RuntimeError. https://github.com/saltstack/pytest-helpers-namespace – s0undt3ch

-1

W innej opcji, to struktura katalogów pracował dla mnie:

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

a potem w my_test.py importu narzędzi przy użyciu: from test_helpers import utils

+0

Uważam, że jest to ta sama sytuacja, którą opisuję w pytaniu, gdzie kod i testy nie są wyraźnie rozdzielone. W przypadku wydań i innych, na przykład trzeba by pomyśleć o wyłączeniu 'test_helpers'. –

5

Można zdefiniować klasę pomocniczą w conftest.py, a następnie utworzyć urządzenie, które zwraca tę klasę (lub jej instancję, w zależności od potrzeb).

import pytest 


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


@pytest.fixture 
def helpers(): 
    return Helpers 

Następnie w badaniach, można użyć urządzenie:

def test_with_help(helpers): 
    helpers.help_me() 
0

Utwórz pakiet pomocników w folderze testy: tests/ helpers/ __init__.py utils.py ... # make sure no __init__.py in here! setup.cfg

w setup.cfg: [pytest] norecursedirs=tests/helpers

pomocnicy będą dostępni pod numerem import helpers.

Powiązane problemy