wake-up-neo.com

einzige Vs pytest

In unittest kann ich setUp-Variablen in einer Klasse setzen, und die Methoden dieser Klasse können dann auswählen, welche Variable sie verwenden möchte.

class test_class(unittest.TestCase):
    def setUp(self):        
        self.varA = 1
        self.varB = 2
        self.varC = 3
        self.modified_varA = 2

    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

Alles in allem war es einfach, eine Reihe von Tests zusammenzustellen, die unter eine Klasse fallen könnten, und dann viele verschiedene Variablen (varA und varB) für verschiedene Methoden zu verwenden. In pytest habe ich ein Fixture in conftest.py erstellt, anstatt eine Klasse in der Klasse, die so alleine ist ...

@pytest.fixture(scope="module")
def input1():
    varA = 1
    varB = 2
    return varA, varB

@pytest.fixture(scope="module")
def input2():
    varA = 2
    varC = 3
    return varA, varC

Ich füge diese Eingabe1 und Eingabe2 meinen Funktionen in einer anderen Datei (sagen wir test_this.py) für zwei verschiedene Funktionen ein. Hier sind die Fragen basierend auf Informationen oben ...

  1. Da ich lokale Variablen nicht einfach in conftest.py deklarieren kann, kann ich diese Datei nicht einfach importieren. Gibt es eine bessere Möglichkeit, verschiedene Variablen zu deklarieren, die in verschiedenen Funktionen in test_this.py verwendet werden können? Ich habe fünf verschiedene Konfigurationen in meinen tatsächlichen Tests für diese Variablen, die definieren, dass viele verschiedene Fixtures in conftest.py verwendet werden und sie als Funktionsargument in fünf verschiedenen Funktionen in test_this.py verwenden. Das klingt schmerzhaft meine Variablen und wählen Sie aus, was ich will

  2. Soll ich globale Variablen einfach in test_this.py deklarieren und sie in den Funktionen nach Belieben verwenden? Scheint ein bisschen nicht Pythonic. Diese Variablen werden nur von den Funktionen in dieser Datei verwendet.

  3. Nehmen wir an, ich habe auch test_that.py und test_them.py. Wenn ich einige gemeinsame Variablen zwischen diesen verschiedenen Dateien habe, wie würde ich sie dann deklarieren? Erstellen Sie einfach eine Datei calle variables.py in dem Verzeichnis, in dem sich all diese Testdateien befinden, und importieren Sie sie wann immer ich brauche? Auf diese Weise kann ich alle Daten getrennt aufbewahren.

  4. Ist es mein Eindruck, dass pytest davon abhält, eine Klasse zu verwenden, um Ihre Funktionen zu organisieren? Bei jedem Beispiel, das ich online lese, scheinen alle Funktionen nur mit Fixtures zu verwenden. Was ist eine Konfiguration zum Definieren von Klassen und Methoden und zum Organisieren von Tests in pytest?

  5. Ich habe ein Testszenario, bei dem ich das Ergebnis einer Funktion in eine andere verwenden muss. Bei pytest habe ich eine Behauptung, dass am Ende einer Funktion kein Return ist, also kann ich diese Funktion nicht als Fixture verwenden. Wie mache ich das? Ich weiß, dass dies keine gute Praxis ist, bei der ein Test von einem anderen abhängt, aber gibt es eine Umgehung?

Vielen Dank im Voraus für Ihre Antworten.

24
LuckyStarr

1) Zuerst können Sie diese Fixtures nicht nur in conftest.py deklarieren, sondern in jedem Python-Modul, das Sie möchten. Und Sie können dieses Modul importieren. Sie können Geräte auch wie die Methode setUp verwenden:

@pytest.fixture(scope='class')
def input(request):
    request.cls.varA = 1
    request.cls.varB = 2
    request.cls.varC = 3
    request.cls.modified_varA = 2

@pytest.usefixtures('input')
class TestClass:
    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

oder Sie können separate Variablen in separaten Fixtures definieren:

def fixture_a():
    return varA

def fixture_b():
    return varB

def fixture_c():
    return varC

def fixture_mod_A():
    return modified_varA

oder machen Sie ein Gerät, das alle Variablen zurückgibt (warum nicht?) oder machen Sie sogar ein indirektes parametrisiertes Gerät, das Variablen nach Ihrer Wahl zurückgibt (ziemlich unübersichtlich)

@pytest.fixture()
def parametrized_iput(request):
   vars = {'varA': 1, 'varB': 2, 'varC': 3}
   var_names = request.param
   return (vars[var_name] for var_name in var_names)

@pytest.mark.parametrize('parametrized_iput', [('varA', 'varC')], indirect=True)
def test_1(parametrized_iput)
   varA, varC = parametrized_iput
   ...

Oder Sie können sogar eine Scheinwerferfabrik herstellen, die im Handumdrehen Leuchten für Sie herstellen wird. Klingt neugierig, wenn Sie nur 5 Tests und 5 Variablenkonfigurationen haben, aber wenn Sie Hunderte von beiden haben, kann dies nützlich sein.

3) Natürlich können Sie. Ich empfehle Ihnen jedoch, diese Datei nicht direkt zu importieren, sondern die Befehlszeilenoption zu verwenden, die auf die zu importierende Datei verweist. In diesem Fall können Sie eine andere Datei mit Variablen verwenden, ohne Ihren Code zu ändern.

4) Ich benutze Klassen in meinen Tests, weil ich vom Nosetest gewechselt bin. Ich habe kein Problem mit Klassen in pytest erwähnt.

5) In diesem Fall schlage ich vor, dass Sie Folgendes tun: Erstellen Sie zuerst die Funktion mit den gewünschten Aktionen:

def some_actions(a, b):
    # some actions here
    ...
    return c

dann verwenden Sie es sowohl im Test als auch im Fixture:

def test():
    assert some_actions(1,2) == 10

@pytest.fixture()
def some_fixture():
     return some_actions(1,2)
19
Ilya Karpeev

Ich denke, das Beste ist leichter zu lesen. Für neue Tester ist unittest wirklich einfach. Es funktioniert aus der Box heraus. Sie sind auf die Python-Implementierung angewiesen, ändern aber in den nächsten Jahren die Schnittstelle nicht. 

Ich organisiere meine Tests gerne so, dass ich maximal 1 Test pro Datei habe. In diesem Fall bin ich nicht auf Klassen angewiesen ... aber ich importiere Klassen aus jedem Test, um Sachen zu machen.

Einige Websites beschweren sich über Farben, die nicht möglich sind. Ich denke, das ist ein Witz, da meine Unittests JUNIT-Ausgabeberichte für Jenkins und andere erstellen. Es gibt großartige Tools (auch nur eine Datei), um JUNIT in eine Website zu konvertieren. Dies ist nicht die Aufgabe eines Testtools.

Einige Leute beschweren sich darüber, dass Sie eine Menge Code benötigen, um einen Versuch zu starten. Ich stimme dem nicht zu, es sind 4 Zeilen Code erforderlich, um einen einzigen Test zu erstellen! Pytest muss jedoch alle schwierigen Anmerkungen kennen, die für einen einfachen Python-Entwickler nicht normal sind.

Ein wichtiger Grund ist auch, dass alle Beteiligten frei bleiben. Wenn Sie jedoch pytest aus irgendeinem Grund verwenden möchten (Bitbucket usw.), gibt es Tools, mit denen Sie Ihre Tests konvertieren und den Code weniger lesbar machen können.

Habe Spaß!

0
Bart Mensfort