wake-up-neo.com

Erstellen und Importieren von Hilfsfunktionen in Tests ohne Erstellen von Paketen im Testverzeichnis mit py.test

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

29

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.

26
sax

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.

14
s0undt3ch

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()
11
augurar

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

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.

0
guyskk