2014-03-25 5 views
22

Ich möchte zusätzliche Setup- und Teardown-Tests vor und nach jedem Test in meiner Testsuite ausführen. Ich habe Fixtures angeschaut, bin mir aber nicht sicher, ob sie der richtige Ansatz sind. Ich muss den Setup-Code vor jedem Test ausführen und ich muss die Teardown-Prüfungen nach jedem Test ausführen.Code vor und nach jedem Test in py.test ausführen?

Mein Anwendungsfall sucht nach Code, der nicht richtig bereinigt: Es hinterlässt temporäre Dateien. In meinem Setup werde ich die Dateien überprüfen und im Teardown überprüfe ich auch die Dateien. Wenn es zusätzliche Dateien gibt, möchte ich, dass der Test fehlschlägt.

Antwort

3

Sie Dekorateure benutzen können, aber programmatisch, so dass Sie den Dekorateur nicht in jedem Verfahren setzen müssen.

ich einige Dinge in der nächsten Code gehe davon aus:

Die Testverfahren sind alle Namen wie: „testXXX()“ Der Dekorateur auf das gleiche Modul hinzugefügt wird, in dem Prüfverfahren durchgeführt werden.

def test1(): 
    print ("Testing hello world") 

def test2(): 
    print ("Testing hello world 2") 

#This is the decorator 
class TestChecker(object): 
    def __init__(self, testfn, *args, **kwargs): 
     self.testfn = testfn 

    def pretest(self): 
     print ('precheck %s' % str(self.testfn)) 
    def posttest(self): 
     print ('postcheck %s' % str(self.testfn)) 
    def __call__(self): 
     self.pretest() 
     self.testfn() 
     self.posttest() 


for fn in dir() : 
    if fn.startswith('test'): 
     locals()[fn] = TestChecker(locals()[fn]) 

Nun, wenn Sie die Testmethoden rufen ...

test1() 
test2() 

Die Ausgabe sollte so etwas wie sein:

precheck <function test1 at 0x10078cc20> 
Testing hello world 
postcheck <function test1 at 0x10078cc20> 
precheck <function test2 at 0x10078ccb0> 
Testing hello world 2 
postcheck <function test2 at 0x10078ccb0> 

Wenn Sie Testmethoden als Klassenmethoden haben, ist der Ansatz auch gültig. Zum Beispiel:

class TestClass(object): 
    @classmethod 
    def my_test(cls): 
     print ("Testing from class method") 

for fn in dir(TestClass) : 
    if not fn.startswith('__'): 
     setattr(TestClass, fn, TestChecker(getattr(TestClass, fn))) 

Der Aufruf TestClass.my_test() druckt:

precheck <bound method type.my_test of <class '__main__.TestClass'>> 
Testing from class method 
postcheck <bound method type.my_test of <class '__main__.TestClass'>> 
+0

Das sieht so aus, als könnte es für freie Funktionen funktionieren. Ich habe auch Klassenfunktionen (obwohl ich versuche, alle Testklassen loszuwerden). –

+0

Es funktioniert auch für die Klassenmethode, ich habe meine Antwort aktualisiert. – Roberto

18

py.test Armaturen ist eine technisch adäquate Methode, um Ihr Ziel zu erreichen.

Sie brauchen nur eine Leuchte, so zu definieren:

@pytest.yield_fixture(autouse=True) 
def run_around_tests(): 
    # Code that will run before your test, for example: 
    files_before = # ... do something to check the existing files 
    # A test function will be run at this point 
    yield 
    # Code that will run after your test, for example: 
    files_after = # ... do something to check the existing files 
    assert files_before == files_after 

Durch Ihre Leuchte mit autouse=True erklärt, wird es automatisch für jede Testfunktion im selben Modul definiert aufgerufen werden.

Das heißt, es gibt eine Einschränkung. Asserting bei Setup/Teardown ist eine umstrittene Praxis. Ich habe den Eindruck, dass die py.test-Hauptautoren es nicht mögen (ich mag es auch nicht, das kann meine eigene Wahrnehmung färben), so dass Sie bei der Vorwärtsbewegung einige Probleme oder Ecken und Kanten bekommen könnten.

+1

Hinweis: Diese Syntax wird seit 3.0 abgeschrieben. Verwende '@ pytest.fixture'. –

+0

Hier ist [der Link] (https://docs.pytest.org/en/latest/fixture.html#fixture-finalization-executing-teardown-code) zu dem vorherigen Kommentar. – Paolo

4

Sie können Module Level Setup/Teardown Fixtures von Pytest verwenden.

Hier ist der Link

http://pytest.org/latest/xunit_setup.html

es funktioniert wie folgt:

def setup_module(module): 
    """ setup any state specific to the execution of the given module.""" 

def teardown_module(module): 
    """ teardown any state that was previously setup with a setup_module 
    method.""" 

Test_Class(): 
     def test_01(): 
      #test 1 Code 

Es wird setup_module vor diesem Test anrufen und teardown_module nach dem Test abgeschlossen ist.

Sie können dieses Gerät in jedes Testskript aufnehmen, um es für jeden Test auszuführen.

Wenn Sie etwas verwenden möchten, die alle Prüfungen in einem Verzeichnis gemeinsam ist, Sie Paket/Verzeichnisebene Befestigungen Nase Rahmen

http://pythontesting.net/framework/nose/nose-fixture-reference/#package

In __init__.py Datei des Pakets verwenden können, können Sie umfassen folgende

 def setup_package(): 
     '''Set up your environment for test package''' 

    def teardown_package(): 
     '''revert the state ''' 
7

Leuchten sind genau das, was Sie wollen. Dafür sind sie bestimmt.

Ob pytest Stil Armaturen verwenden oder Setup und Teardown (Modul, eine Klasse oder Methode Ebene) xUnit Stil Armaturen, hängt von den Umständen und persönlichem Geschmack.

Von dem, was Sie beschreiben, scheint es, als ob Sie pytest autouse fixtures verwenden könnten.
Oder xUnit Stil Funktionsebene setup_function()/teardown_function().

Pytest hat Sie vollständig abgedeckt. So sehr, dass es vielleicht ein Feuerschlauch von Informationen ist.

Verwandte Themen