2013-03-18 11 views
9

Ist es möglich, dass eine Unterkontextklasse einen anderen Unterkontext erweitert und Funktionen außer Kraft setzt?Ist es möglich, Schrittdefinitionen in einem Behat-Kontext zu überschreiben?

Derzeit Ich habe

class TestContext extends BehatContext { 
    /** 
    * @Given /^a testScenarioExists$/ 
    */ 
    public function aTestscenarioexists() { 
     echo "I am a generic test scenario\n"; 
    } 
} 

und

class SpecialTestContext extends TestContext { 
    /** 
    * @Given /^a testScenarioExists$/ 
    */ 
    public function aTestscenarioexists() { 
     echo "I am a special test scenario\n"; 
    } 
} 

Im Feature Kontext ich es sagen uns die SpecialTestContext als Subkontext.

Wenn ich laufe der Test Behat klagt mit

[Behat \ Behat \ Exception \ RedundantException]
Step "/^a testScenarioExists $ /" ist bereits definiert in SpecialTestContext :: aTestscenarioexists()

Kann mir bitte jemand in die richtige Richtung zeigen?

Um einige weitere Informationen zu geben, warum ich versuche, dies zu erreichen, was ich versuche, die Fähigkeit zu erreichen, ist Szenarien mit unterschiedlichen Umgebungen zu laufen, und haben die Umgebung, in der gherkin-Datei angegeben, zum Beispiel:

Scenario: Test with generic environment 
Given I am in the environment "generic" 
    And a test scenario exists 

Scenario: Test with specialised environment 
Given I am in the environment "specialised" 
    And a test scenario exists 

Ich kann dann Code in FeatureContext hinzufügen, um den richtigen Sub-Kontext zu laden.

Antwort

4

Kurz gesagt ... das ist nicht möglich: http://docs.behat.org/guides/2.definitions.html#redundant-step-definitions

In Bezug auf die Lade Subkontexte dynamisch, dies nicht möglich ist:

  1. Subkontexte geladen zu 'Kompilierung' - dh. im Haupt FeatureContext Konstruktor
  2. Als der erste Schritt Definition ausgeführt wird, hat Behat bereits alle Anmerkungen gesammelt und kartiert sie Definitionen zu dem Schritt, nicht mehr kann/sollte

Check this out zu verstehen, wie hinzugefügt werden ein Context verhält: http://docs.behat.org/guides/4.context.html#contexts-lifetime

Paar breiterer Dinge zu beachten:

  1. Alles, was in einem gherkin Szenario mus erfasst t verständlich für Nicht-Entwickler (oder zumindest für Entwickler, die das System nicht geschrieben haben!).Ein Szenario sollte eine (idealerweise nicht mehr) Geschäftsregel vollständig enthalten, ohne sich in irgendeinen Code einarbeiten zu müssen

  2. Sie wollen nicht zu viel Logik in Schrittdefinitionen verstecken, irgendwelche Regeln sollten in a erfasst werden gherkin Szenario

  3. Es ist bis zu Ihrem, wie Sie Ihre FeatureContexts organisieren, aber Sie dies in Ihrem System nach Themen/domains tun, gehen zu wollen, zum Beispiel:

    • ein DatabaseContext mit dem Lesen betroffen sein kann + Schreiben in einen Test db
    • ein ApiContext Schritte befasst sich mit der Validierung eines api in Ihrem System enthalten
    • ein CommandContext betroffen sein können Befehle Ihre Systeme Konsole mit Validierung
+0

Aktualisiere nur die oben angegebenen Links. * http://docs.behat.org/en/latest/user_guide/context/definitions.html#redundant-step-definitions * http://docs.behat.org/en/latest/user_guide/context. html # contexts-lifetime – aczietlow

9

Als Rob Squires erwähnte der dynamischen Kontext Laden wird nicht funktionieren.

Aber ich habe eine Problemumgehung für das Überschreiben von Schrittdefinitionen, die ich regelmäßig verwende. Bitte notieren Sie Ihre Methode nicht. Behat wird die Annotation der überschriebenen Methode in der Oberklasse übernehmen und diesen Methodennamen dem passenden Schritt zuordnen. Wenn ein übereinstimmender Schritt gefunden wird, wird die Methode in Ihrer Unterklasse aufgerufen. Um es deutlich zu machen, verwende ich die Annotation @override dafür. Die Annotation @override hat für Behat keine besondere Bedeutung.

class SpecialTestContext extends TestContext { 
    /** 
    * @override Given /^a testScenarioExists$/ 
    */ 
    public function aTestscenarioexists() { 
     echo "I am a special test scenario\n"; 
    } 
} 
+1

Dies ist die eigentliche Lösung - überschreiben Methoden in der Unterklasse, ohne den Muster-Docblock zu ändern. –

0

Überschriebene Methode kann nicht mit demselben Satz definiert werden.

class SpecialTestContext extends TestContext { 

    public function aTestscenarioexists() { 
    echo "I am a special test scenario\n"; 
    } 
} 
Verwandte Themen