Frage
Wie kann ich Hilfsfunktionen in Testdateien importieren, ohne Pakete im Verzeichnis test
zu erstellen?
Kontext
Ich möchte eine Test-Helfer-Funktion erstellen, die ich in mehreren Tests importieren kann. Sprich so etwas:
# 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 verwenden, mit py.test 2.8.2
Aktuelle "Lösung"
Zur Zeit mache ich dies durch Importieren eines Moduls in das test
-Verzeichnis meines Projekts (das jetzt ein Paket ist), aber ich möchte es mit einem anderen Mechanismus tun, wenn möglich (damit mein test
-Verzeichnis keine Pakete hat, sondern nur Tests und die Tests können auf einer installierten Version des Pakets ausgeführt werden, wie dies empfohlen wird hier in der py.test-Dokumentation zu bewährten Verfahren ).
meine Option ist es, ein zusätzliches Verzeichnis in tests
dir zu erstellen und es so im conftest zu pythonpath hinzuzufügen.
tests/
helpers/
utils.py
...
conftest.py
setup.cfg
im conftest.py
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers'))
in setup.cfg
[pytest]
norecursedirs=tests/helpers
dieses Modul ist mit import utils
verfügbar. Achten Sie nur auf Namenskonflikte.
Auf der Suche nach einer Lösung für dieses Problem stieß ich auf diese SO Frage und entschied mich schließlich für denselben Ansatz. Ein Hilfspaket erstellen, sys.path
importieren und importieren und dann einfach importieren ...
Dies schien nicht der beste Ansatz zu sein, also habe ich pytest-helpers-namespace erstellt. Mit diesem Plugin können Sie Hilfsfunktionen für Ihren conftest.py
registrieren:
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
Und dann verwenden Sie es innerhalb eines Testfall-Funktionskörpers wie
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)
Es ist ziemlich einfach und die Dokumentation ziemlich klein. Schau es dir an und sag mir, ob es auch dein Problem anspricht.
Sie können eine Hilfsklasse in conftest.py definieren und dann ein Fixture erstellen, das diese Klasse (oder eine Instanz davon, je nach Bedarf) zurückgibt.
import pytest
class Helpers:
@staticmethod
def help_me():
return "no"
@pytest.fixture
def helpers():
return Helpers
Dann können Sie in Ihren Tests das Gerät verwenden:
def test_with_help(helpers):
helpers.help_me()
Um auf eine Methode aus verschiedenen Modulen zuzugreifen, ohne Pakete zu erstellen, und diese Funktion als Hilfsfunktion verwenden, fand ich folgendes hilfreich:
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")
Erstellen Sie ein Hilfspaket im Testordner:
tests/
helpers/
__init__.py
utils.py
...
# make sure no __init__.py in here!
setup.cfg
in setup.cfg:
[pytest]
norecursedirs=tests/helpers
die Helfer stehen mit import helpers
zur Verfügung.