2015-01-14 19 views
15

In Unittest, ich setUp Variablen in einer Klasse und dann können die Methoden dieser Klasse wählten je nachdem, welche Variable es verwenden möchte ...Unittest Vs pytest

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 

So in Unittest, es war einfach zu setzen Bündel von Tests zusammen, die unter einer Klasse gehen könnten und dann viele verschiedene Variablen (varA und varB) für verschiedene Methoden verwenden. In pytest, habe ich eine feste Größe in conftest.py statt einer Klasse in Unittest, wie dieser ...

@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üttere diese input1 und input2 meiner Funktionen in einer anderen Datei (sagen wir mal test_this.py) für zwei verschiedene Funktionen. Hier sind die auf Informationen basieren Fragen über ...

  1. Da ich nicht nur lokale Variablen in conftest.py erklären kann, wie ich kann nicht einfach diese Datei importieren. Gibt es hier 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 meinem tatsächlichen Testen für diese Variablen, definieren, dass viele verschiedene Fixtures in conftest.py und verwenden sie als Funktion Argument in fünf verschiedenen Funktionen in test_this.py klingt schmerzhaft, würde ich lieber zurück zur unittest Klassenstruktur, definieren Meine Variablen und wählen Sie, was ich will

  2. Sollte ich nur globale Variablen in test_this.py deklarieren und sie in den Funktionen verwenden, wie ich will? Scheint ein bisschen nicht pythonisch. Diese Variablen werden nur von den Funktionen in dieser Datei verwendet.

  3. Sagen wir, 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 deklarieren? Erstellen Sie einfach eine Datei namens calle variables.py in dem Verzeichnis, in dem sich all diese Testdateien befinden, und führen Sie einen Import durch, wann immer ich es 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? Jedes Beispiel, das ich online lese, scheint 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, wo ich Ergebnis einer Funktion in eine andere verwenden muss. Mit pytest habe ich eine Assert, dass am Ende einer Funktion keine Rückkehr ist, so dass ich diese Funktion nicht als Fixture verwenden kann. Wie erreiche ich das? Ich weiß, dass das keine gute Übung ist, dass mein Test sich auf einen anderen stützt, aber gibt es da eine Arbeit?

Vielen Dank im Voraus für Ihre Antworten.

Antwort

10

1) Zuerst können Sie diese Fixtures nicht nur in conftest.py deklarieren, sondern in jedem Python-Modul, das Sie wollen. Und Sie können dieses Modul importieren. Sie können auch Vorrichtungen in der gleichen Art und Weise verwenden, wie Sie Setup-Methode verwendet:

@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 separate Variablen in separaten Vorrichtungen definieren:

def fixture_a(): 
    return varA 

def fixture_b(): 
    return varB 

def fixture_c(): 
    return varC 

def fixture_mod_A(): 
    return modified_varA 

oder einer Aufspannung machen, die die Variablen alle zurückgibt (warum nicht?) oder auch indirekte parametrisierte Befestigung machen die Variablen durch Ihre Wahl zurückgibt (ziemlich verwirrend Weg):

@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 auch Sie können Befestigungs Fabrik machen die Vorrichtungen für Sie on the fly machen. Klingt seltsam, wenn Sie nur 5 Tests und 5 Konfigurationen von Variablen haben, aber wenn Sie Hunderte von beiden erhalten, kann es 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 auswählen, ohne den Code zu ändern.

4) Ich verwende Klassen in meinen Tests, weil ich von nosetest migrierte. Ich habe kein Problem mit Klassen in Pytest erwähnt.

5) In diesem Fall schlage ich vor, Sie das tun folgende: Faust die Funktion mit den gewünschten Aktionen machen:

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

es dann sowohl den Einsatz in Test und Vorrichtungsbau:

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

@pytest.fixture() 
def some_fixture(): 
    return some_actions(1,2) 
+0

Thanks a Haufen, das hilft. – LuckyStarr