2017-05-26 5 views
0

Ich teste eine Webseite, die, sagen wir, drei verschiedene Module enthält. In meinem Test-Framework wird jedes Seitenmodul durch eine eigene Testklasse dargestellt: Module1Tests, Module2Tests, Module3Tests. Um spezifische Bedingungen für jedes Modul zu erfüllen, verwende ich außerdem Assume.That in jeder der Testklassen. Mit diesem Setup funktioniert alles gut, wenn ich nur einzelne Module teste. Aber, wenn ich eine Testklasse für die ganze Seite zu erstellen und zu verwenden Assert.Multiple wie folgt aus:NUnit: Assert.Multiple für Methoden, die Assume.That enthalten

public class HomePageTests 
    { 
     public Module1Tests Module1Tests { get; } = new Module1Tests(); 

     public Module2Tests Module2Tests { get; } = new Module2Tests(); 

     public Module3Tests Module3Tests { get; } = new Module3Tests(); 

[Test] 
public void HomePage() 
{ 
    Assert.Multiple(() => 
    { 
     Module1Tests.Module1TestMethod(); 
     Module2Tests.Module2TestMethod(); 
     Module3Tests.Module3TestMethod(); 
    }); 
} 

ich Fehlermeldung bekommen, dass ich diese Methoden nicht mit Assume.That innerhalb Assert.Multiple Blöcke verwenden können.

Ich habe auch versucht, Modul Testmethoden ohne Block aufrufen, aber der ganze Seite Test stoppt Ausführung beim ersten Fehler.

Gibt es eine Möglichkeit, dies zu beheben? Im Grunde möchte ich nur einen Test für die Seite haben, die bestanden würde, wenn alle zugrundeliegenden Modultests bestanden werden.

+0

Es scheint zu [dokumentiert] (https://github.com/nunit/docs/wiki/Multiple-Asserts) Verhalten (Nummer 6 in Die Liste). Nicht sicher, warum sie das getan haben, aber es scheint absichtlich zu sein. –

+0

Ja, das ist Absicht. Ich hoffe, dass es einen anderen Weg geben muss, um mein Ziel zu erreichen. – YMM

Antwort

0

Wie bereits erwähnt wurde, und wie die Nachricht anzeigt, können Sie keine Annahmen innerhalb eines Mehrfach-Bestätigungsblocks verwenden. Wenn Sie sich die Liste der ausgeschlossenen Elemente in Anmerkung 6 auf der Seite "Annahmen" der Dokumentation ansehen, werden Sie feststellen, dass es sich um alle Elemente handelt, die die Ausführung des Tests sofort beenden sollen.

Assert.Fail sowie fehlgeschlagene Assertions sollen natürlich auch den Test sofort beenden. Mehrere Assertionen machen eine Ausnahme ... der Fehler wird aufgezeichnet, aber der Test wird erst beendet, wenn alle verschachtelten Assert.Multiple-Blöcke beendet sind.

Ich überlegte, einige Ausnahmen für jeden der Punkte auf der Liste zu machen, was es erforderlich gemacht hätte, für jedes von ihnen ein neues Verhalten zu definieren. Es war nicht klar, was das beste alternative Verhalten wäre, also entschied ich mich, auf Benutzerfeedback zu warten. Diese SO-Frage ist eigentlich das erste Feedback, das ich irgendwo gesehen habe, also danke!

Im Allgemeinen werden Annahmen vor allen Assertionen platziert, manchmal sogar in der SetUp-Methode. Ihre Bedeutung in diesem Fall ist im Wesentlichen: "Wenn diese Annahme fehlschlägt, dann macht es keinen Sinn, den Test durchzuführen." Gelegentlich werden sie nach ein paar Behauptungen platziert, was bedeutet: "Wenn dies fehlschlägt, macht es keinen Sinn, weitere Tests durchzuführen."

Wenn ich Sie richtig verstehe, möchten Sie eine fehlgeschlagene Annahme, dass wir alle folgenden Behauptungen in einem Ihrer Modultests überspringen sollten, aber mit anderen Modultests fortfahren. Aber die Idee eines Modultests in einem Testfall ist zumindest heute nicht in NUnit vorhanden. Die Strukturierung für Sie in NUnit wird durch die Hierarchie dargestellt: * Namespace (möglicherweise verschachtelte) * Fixture * Test Case * Mehrere Assert Block (möglicherweise verschachtelte) * Assertions

Wenn Ihr Modultests eine Mehrfachnutzung Assert Block selbst, dann könnten wir in Betracht ziehen, das Verhalten von Assume innerhalb eines multiplen Asser-Blocks so zu unterteilen, dass es "keinen Sinn macht, mehr Testcode in diesem Block zu verwenden". Wenn Sie das möchten, müssen Sie eine Feature-Anforderung auf GitHub ablegen. Ich kann Ihnen sagen, dass es keine triviale Veränderung ist, also ist es nicht garantiert, dass wir es tun würden, aber es könnte sich lohnen, eine Analyse zu machen, um zu sehen, wie es funktionieren könnte. Grundsätzlich möchten wir Ihnen das geben, was Sie brauchen, ohne andere Benutzer zu verwirren.:-)

Mit aktuellen Fähigkeiten, ich sehe zwei Möglichkeiten, dieses Problem zu umgehen:

  1. jeden Modul Test innerhalb einer Halterung ein separates Testverfahren Stellen, die im Wesentlichen der aktuellen Testverfahren ersetzt. Legen Sie das Order-Attribut für jeden Test fest, wenn die Reihenfolge der Ausführung für Sie wichtig ist. Mit anderen Worten, Ihr existierendes Gerät mit n Tests würde zu separaten Geräten werden. Ich weiß nicht, ob dies für Sie möglich ist, da ich Ihren Code nicht gesehen habe, aber es ist eine Möglichkeit, die vorhandenen Funktionen von NUnit für Strukturierungstests zu nutzen.

  2. Verkapseln Sie Ihre Modultests als eine Reihe von Klassen und nicht als eine Reihe von Methoden. Führen Sie alle Ihre Annahmen mit einer Methode und all Ihren Behauptungen mit einer anderen Methode aus. Rufe alle Annahmen vor deinem Assert.Multiple-Block auf. Wenn Sie nicht möchten, dass fehlgeschlagene Annahmen den gesamten Test stoppen, müssen Sie einen Bool-Wert aus dem Annahmeneintrag zurückgeben und sich daran erinnern, ob jedes Modul ausgeführt werden soll.

  3. Wahrscheinlich der einfachste: Machen Sie Ihre Annahmen in Bedingungen innerhalb jeder Modul Testmethode. Wenn die Annahmen fehlschlagen, führen Sie die Tests nicht aus.

Was ich wirklich wünsche ich als Alternative zur Strukturierung bieten könnte, ist verschachtelte Vorrichtungen. In vielerlei Hinsicht würde das zu dem passen, was Sie besser machen wollen als die anderen Optionen. Obwohl NUnit es erlaubt, Fixtures syntaktisch zu verschachteln, wird die Verschachtelung leider vollständig ignoriert, wenn die Tests ausgeführt werden. Wir haben eine herausragende Funktion, dies zu ändern, aber es ist ziemlich futuristisch.

  1. Replac
+0

Danke für so eine ausführliche Antwort, @Charlie! Vorschlag 1 war der erste Versuch, bevor ich meine Frage hier veröffentlichte. Ich hatte eine Seitentestklasse mit drei "Test" -Blöcken, wobei jeder Block eine Methode darstellt, die die Modultestmethode aus Modultestklassen aufruft. Eigentlich funktioniert es, aber das Problem ist, dass ich parametrisierte Testmethoden für Module verwende (mit '[Values]' und '[ValueSource]' - Attributen) und die gleichen Parameterblöcke für jedes Modul zu wiederholen, scheint mir nicht elegant zu sein. Ich habe die Parametrierung auf Fixture-Ebene versucht, aber ich kann das Attribut [[ValueSource]] dort nicht verwenden. – YMM

+0

Vorschlag 3 sieht gut aus, aber wie kann ich den Test nicht ausführen, wenn die Bedingung nicht erfüllt ist? Zum Beispiel verwende ich 'if', um nach einer booleschen Bedingung zu suchen, und wenn es nicht wahr ist, was soll ich tun, um den Test zu überspringen? Der Aufruf von 'Assert.Inclusive' ist aus dem gleichen Grund nicht erlaubt. – YMM

+0

Ich gehe davon aus, dass Sie von Ihrem Modultest zurückkehren und die Kontrolle an die Testmethode selbst zurückgeben würden, die dann den nächsten Modultest aufrufen würde. – Charlie

Verwandte Themen