webentwicklung-frage-antwort-db.com.de

Code vor und nach jedem Test in py.test ausführen?

Ich möchte vor und nach jedem Test in meiner Testsuite zusätzliche Setup- und Teardown-Prüfungen durchführen. Ich habe mir Fixtures angesehen, bin mir aber nicht sicher, ob sie korrekt sind. Ich muss den Setup-Code vor jedem Test ausführen und die Abreißprüfungen nach jedem Test ausführen.

In meinem Anwendungsfall wird nach Code gesucht, der nicht ordnungsgemäß bereinigt wird: temporäre Dateien bleiben erhalten. In meinem Setup überprüfe ich die Dateien und im Abriß überprüfe ich auch die Dateien. Wenn es zusätzliche Dateien gibt, möchte ich, dass der Test fehlschlägt.

27

py.test Fixtures sind eine technisch angemessene Methode, um Ihren Zweck zu erreichen.

Sie müssen nur ein Gerät so definieren:

@pytest.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

Wenn Sie Ihr Gerät mit autouse=True deklarieren, wird es automatisch für jede im selben Modul definierte Testfunktion aufgerufen.

Das heißt, es gibt einen Vorbehalt. Das Festlegen beim Setup/Abreißen ist eine umstrittene Praxis. Ich habe den Eindruck, dass die Hauptautoren von py.test es nicht mögen (ich mag es auch nicht, so dass meine eigene Wahrnehmung möglicherweise gefärbt wird), so dass Sie beim Fortschreiten auf einige Probleme oder Ecken und Kanten stoßen können.

29
tawmas

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

Ob Sie pytest-Stilfixtures oder setup und teardown (Modul-, Klassen- oder Methodenebene) xUnit-Style-Fixtures verwenden, hängt von den Umständen und dem persönlichen Geschmack ab.

Nach dem, was Sie beschreiben, scheint es, als könnten Sie pytest autouse fixtures verwenden.
Oder xUnit-Style-Funktionsstufe setup_function ()/teardown_function () .

Pytest hat dich komplett abgedeckt. So sehr, dass es vielleicht ein Feuerwehrschlauch von Informationen ist.

8
Okken

Sie können Setup-/Teardown-Fixtures von Modul auf Modulebene 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

Vor diesem Test wird setup_module und nach Abschluss des Tests teardown_module aufgerufen.

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

WENN Sie etwas verwenden möchten, das für alle Tests in einem Verzeichnis üblich ist 

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

In __init__.py-Datei des Pakets können Sie Folgendes einfügen

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

     def teardown_package():
        '''revert the state '''
5
Arvind

Sie können Dekoratoren jedoch programmgesteuert verwenden, so dass Sie den Dekorator nicht in jede Methode einfügen müssen.

Ich gehe davon aus, dass es im nächsten Code mehrere Dinge gibt:

Die Testmethoden heißen alle wie folgt: "testXXX ()" Der Dekorator wird demselben Modul hinzugefügt, in dem Testmethoden implementiert sind.

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

Wenn Sie jetzt die Testmethoden aufrufen ...

test1()
test2()

Die Ausgabe sollte ungefähr so ​​aussehen:

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 verwenden, ist der Ansatz ebenfalls 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 an TestClass.my_test() wird gedruckt:

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

Werfen Sie einen Blick auf Python-Dekorateure https://wiki.python.org/moin/PythonDecorators

0
venpa

Fixtures haben standardmäßig scope=function. Wenn Sie also nur eine Definition wie verwenden

@pytest.fixture
def fixture_func(self)

Der Standardwert ist (Bereich = 'Funktion'). 

Daher werden alle Finalisierungen in der Fixture-Funktion nach jedem Test aufgerufen.

Ref: .__ 1. http://programeveryday.com/post/pytest-creating-and- using-fixtures-for-streamline-testing/

0
alpha_989