2017-09-04 2 views
2

house.py:Wie eine Klasse testen Methoden in pytest geerbt

class House: 
    def is_habitable(self): 
     return True 

    def is_on_the_ground(self): 
     return True 

conftest.py:

import pytest 
from house import House 


@pytest.fixture(scope='class') 
def house(): 
    return House() 

test_house.py:

class TestHouse: 
    def test_habitability(self, house): 
     assert house.is_habitable() 

    def test_groundedness(self, house): 
     assert house.is_on_the_ground() 

Bis zu diesem Zeitpunkt getestet wird alles wird.

Nun füge ich eine Unterklasse und überschreiben Sie eine Methode in house.py:

class House: 
    def is_habitable(self): 
     return True 

    def is_on_the_ground(self): 
     return True 


class TreeHouse(House): 
    def is_on_the_ground(self): 
     return False 

Ich füge auch eine neue Halterung für diese Klasse in conftest.py:

import pytest 
from house import House 
from house import TreeHouse 


@pytest.fixture(scope='class') 
def house(): 
    return House() 


@pytest.fixture(scope='class') 
def tree_house(): 
    return TreeHouse() 

ich fügen Sie eine neue Testklasse für Baum Haus in test_house.py:

class TestHouse: 
    def test_habitability(self, house): 
     assert house.is_habitable() 

    def test_groundedness(self, house): 
     assert house.is_on_the_ground() 


class TestTreeHouse: 
    def test_groundedness(self, tree_house): 
     assert not tree_house.is_on_the_ground() 

In diesem poi Nein, der Code funktioniert, aber es gibt Fälle, die nicht getestet werden. Um zum Beispiel zu vervollständigen, müsste ich erneut die Methoden testen, die von House in TreeHouse geerbt wurden.

Das Umschreiben der gleichen Tests von TestHouse wäre nicht DRY.

Wie kann ich die geerbte Methode TreeHouse (in diesem Fall is_habitable) ohne Duplizierungscode testen?

Ich möchte etwas wie das Testen der TreeHouse mit den gleichen Tests, die seine Super-Klasse durchläuft, aber nicht für die Methoden/Eigenschaften, die neu oder außer Kraft gesetzt sind.

Nach einigen Recherchen stieß ich auf widersprüchliche Quellen. Und nachdem ich die pietäteste Dokumentation ausgegraben habe, verstehe ich nicht, was auf dieses Szenario zutrifft.

Ich interessiere mich für die pytest Weg, dies zu tun. Bitte verweisen Sie auf die Dokumentation und erklären Sie, wie das hier zutrifft.

+0

Ihre allerletzte Zeile sollte 'assert not tree_house.is_on_the_ground() 'sein –

+0

danke für die Bearbeitung @PaulH – Bastian

+0

@PaulH Ich denke, ich könnte auch loswerden der' == True' in den anderen behauptet. – Bastian

Antwort

3

Eine Möglichkeit, dies zu tun wäre, um das Gerät Namen zu verwenden house für alle Testverfahren (auch wenn es eine TreeHouse Prüfung) und override its value in each test context:

class TestTreeHouse(TestHouse): 
    @pytest.fixture 
    def house(self, tree_house): 
     return tree_house 

    def test_groundedness(self, house): 
     assert not house.is_on_the_ground() 

Auch TestTreeHouse erbt von TestHouse beachten. Da pytest merely enumerates methods of classes (d. H. Es gibt keine "Registrierung" mit beispielsweise einem @pytest.test() Dekorator), werden alle in TestHouse definierten Tests in Unterklassen davon ohne weiteren Eingriff entdeckt.

+1

Ich mag die Antwort. Auf diese Antwort: https://stackoverflow.com/a/44431292/1075374 obwohl es gesagt wird, dass pytest Klassenhierarchien verbietet, obwohl der Link es nicht erklärt. Hast du eine Meinung dazu? – Bastian

+0

Ich habe das ausprobiert und aus irgendeinem Grund geht 'sich selbst' in die Quere. 'TestTreeHouse.test_habitability' ->' TypeError: is_habitable() fehlt 1 benötigtes Positionsargument: 'self''. Das gleiche passiert mit dem zweiten Test. Irgendeine Idee? – Bastian

+0

Vielleicht geben Sie das * Klassenobjekt * 'TreeHouse' aus dem' tree_house' Fixture zurück, anstelle einer Instanz der Klasse: 'TreeHouse()' – theY4Kman

0

Sie können pytest parameterization verwenden, um mehrere Argumente an denselben Test zu übergeben. In diesem Fall würde das Argument höchstwahrscheinlich die zu testende Klasse sein.

+0

Danke für den Link. Ich verwende Parameter, um Tests mit verschiedenen Parametern/Argumenten zu wiederholen. Aber ich sehe nicht, wie das in diesem Zusammenhang funktionieren würde. Möchten Sie Ihre Antwort weiter ausbauen als nur einen Link zu den Dokumenten, indem Sie etwas Arbeitscode klären und zeigen? – Bastian

Verwandte Themen