Frage

Ich benutze Assert.Fail viel, wenn TDD tun. Ich arbeite in der Regel auf der einen Test zu einer Zeit, aber wenn ich Ideen für die Dinge möchte ich später implementieren ich einen leeren Test schnell schreiben, in dem der Name der Testmethode gibt an, was ich als eine Art von todo-Liste implementieren möchten. Um sicherzustellen, dass ich nicht vergessen, dass ich eine Assert.Fail put () im Körper.

Wenn xUnit.Net Ausprobieren fand ich sie Assert.Fail nicht umgesetzt hatte. Natürlich kann man immer Assert.IsTrue (false), aber das ist meine Absicht auch nicht kommunizieren. Ich habe den Eindruck Assert.Fail wurde nicht absichtlich umgesetzt. Ist dies als schlechte Praxis? Wenn ja, warum?


@ Martin Meredith Das ist nicht genau das, was ich tue. Ich habe einen Test zuerst schreiben und dann Code implementieren, damit es funktioniert. Normalerweise denke ich an mehreren Tests auf einmal. Oder ich denke, über einen Test zu schreiben, wenn ich auf etwas anderes arbeite. Das ist, wenn ich einen leeren andernfalls Test zu erinnern, schreiben. Mit der Zeit bekomme ich den Test zu schreiben I Test-First ordentlich arbeiten.

@Jimmeh Das sieht aus wie eine gute Idee. Ignoriert Tests nicht scheitern, aber sie zeigen immer noch in einer separaten Liste nach oben. Müssen versuchen, dass aus.

@ Matt Howells Großartige Idee. NotImplementedException kommuniziert Absicht besser als assert.Fail () in diesem Fall

@Mitch Weizen Das ist, was ich suchte. Es scheint, es wurde weggelassen, damit sie nicht auf andere Weise missbraucht ich es missbrauchen.

War es hilfreich?

Lösung

Für dieses Szenario eher als Aufruf Assert.Fail, ich die folgende (in C # / NUnit)

[Test]
public void MyClassDoesSomething()
{
    throw new NotImplementedException();
}

Es ist expliziter als ein Assert.Fail.

Es scheint allgemeine Übereinstimmung zu sein, ist es vorzuziehen, explizite Behauptungen als Assert.Fail () zu verwenden. Die meisten Frameworks müssen es aber enthalten, weil sie eine bessere Alternative bieten nicht. Zum Beispiel NUnit (und andere) bieten eine ExpectedExceptionAttribute zu testen, dass einiger Code, der eine bestimmte Klasse von Ausnahme auslöst. Um jedoch, dass eine Eigenschaft auf der Ausnahme zu testen, um einen bestimmten Wert eingestellt ist, kann man es nicht verwenden. Stattdessen müssen Sie Assert.Fail greifen:

[Test]
public void ThrowsExceptionCorrectly()
{
    const string BAD_INPUT = "bad input";
    try
    {
        new MyClass().DoSomething(BAD_INPUT);
        Assert.Fail("No exception was thrown");
    }
    catch (MyCustomException ex)
    {
         Assert.AreEqual(BAD_INPUT, ex.InputString); 
    }
}

Die xUnit.Net Methode Assert.Throws macht dies viel sauberere ohne eine Assert.Fail Methode erfordert. Durch den Verzicht auf eine Assert.Fail () -Methode einschließlich xUnit.net Entwickler ermutigt zu finden und explizite Alternativen zu verwenden, und die Schaffung neuer Behauptungen zu unterstützen, wo nötig.

Andere Tipps

Es wurde absichtlich weggelassen. Dies ist Brad Wilson Antwort, warum gibt es keine Assert.Fail ():

  

Wir haben das nicht übersehen, eigentlich. ich   finden Assert.Fail ist eine Krücke die   bedeutet, dass es wahrscheinlich eine ist   Behauptung fehlt. Manchmal ist es einfach   die Art, wie der Test aufgebaut ist, und   manchmal ist es, weil durchsetzen konnte   Verwenden Sie eine andere Behauptung.

Ich habe immer Assert.Fail () für den Umgang mit Fällen, in denen Sie, dass ein Test durch Logik erkannt haben über einfachen Wertvergleich ausfallen soll. Als ein Beispiel:

try 
{
  // Some code that should throw ExceptionX
  Assert.Fail("ExceptionX should be thrown")
} 
catch ( ExceptionX ex ) 
{
  // test passed
}

Damit das Fehlen Assert.Fail () im Rahmen sieht aus wie ein Fehler zu mir. Ich würde die Assert Klasse schlage Patchen eine fail () Methode zu schließen, und dann den Patch auf den Framework-Entwickler einreichen, zusammen mit Ihrer Argumentation es hinzuzufügen.

Wie für Ihre Praxis-Tests zu schaffen, die absichtlich in Ihrem Arbeitsbereich nicht, um sich zu erinnern, sie zu implementieren, bevor begehen, die mir wie eine feine Praxis scheint.

I MbUnit für meine Unit-Tests verwenden. Sie haben die Möglichkeit, Tests zu ignorieren, die als orange zeigen (und nicht grün oder rot) in der Testsuite. Vielleicht hat xUnit etwas ähnliches, und würde bedeuten, Sie haben nicht einmal jeder behauptet in die Methode setzen müssen, weil sie in einer anderen Farbe annoyingly auftauchen würden es schwer zu verpassen machen?

Edit:

In MbUnit es in der folgenden Art und Weise ist:

[Test]
[Ignore]
public void YourTest()
{ } 

Dies ist das Muster, das ich benutze, wenn ein Test für Code writting, die ich will eine Ausnahme von Design werfen:

[TestMethod]
public void TestForException()
{
    Exception _Exception = null;

    try
    {
        //Code that I expect to throw the exception.
        MyClass _MyClass = null;
        _MyClass.SomeMethod();
        //Code that I expect to throw the exception.
    }
    catch(Exception _ThrownException)
    {   
        _Exception = _ThrownException
    }
    finally
    {
        Assert.IsNotNull(_Exception);
        //Replace NullReferenceException with expected exception.
        Assert.IsInstanceOfType(_Exception, typeof(NullReferenceException));
    }
}

IMHO ist dies eine bessere Art und Weise der Prüfung auf Ausnahmen gegenüber der Verwendung Assert.Fail (). Der Grund dafür ist, dass nicht nur ich teste eine Ausnahme überhaupt geworfen, aber ich teste auch für den Ausnahme-Typen. Mir ist klar, dass dies auf die Antwort von Matt Howells ähnlich ist, aber meiner Meinung nach mit dem finally-Block ist robuster.

Natürlich wäre es noch möglich sein, andere Assert Methoden gehört die Ausnahmen Eingabezeichenfolge usw. zu testen, würde ich für Ihre Kommentare und Ansichten auf meinem Muster dankbar sein.

Persönlich habe ich kein Problem mit der Verwendung einer Testsuite als ToDo-Liste wie diese so lange wie Sie schließlich umgehen, um den Test zu schreiben vor Sie den Code implementieren zu übergeben.

Having said that, habe ich das selbst verwenden nähern, obwohl jetzt, wo ich zu finden bin damit führt mich auf einen Weg zu viele Tests des Schreibens im Voraus, die in eine seltsame Art und Weise wie das umgekehrte Problem ist nicht das Schreiben von Tests überhaupt: Entscheidungen über Design ein wenig zu früh IMHO Sie am Ende

.

Im übrigen in MSTest, die Standard-Test-Vorlage verwendet Assert.Inconclusive am Ende ihrer Proben.

AFAIK der xUnit.NET Rahmen soll extrem leicht sein und ja, haben sie Ausfallen absichtlich geschnitten, um den Entwickler zu ermutigen, eine explizite Fehlerbedingung zu verwenden.

wilde Vermutung: Quellen Assert.Fail soll Sie aufhören zu denken, dass ein guter Weg, Test-Code zu schreiben, ist wie ein riesiger Haufen Spaghetti auf ein Assert.Fail in den schlimmen Fällen führt. [Bearbeiten hinzuzufügen: andere Leute Antworten diese im Großen und Ganzen bestätigen, aber mit Zitaten]

Da das ist nicht das, was du tust, ist es möglich, dass xUnit.Net überbeschützend wird.

Oder vielleicht nur denken, dass sie es ist so selten und so unorthogonal als unnötig.

Ich ziehe es eine Funktion namens ThisCodeHasNotBeenWrittenYet (eigentlich etwas kürzer, für eine einfache Typisierung) zu implementieren. Kann nicht die Absicht deutlicher als die kommunizieren, und Sie haben eine genaue Suchbegriff ein.

Ob das nicht funktioniert, oder nicht implementiert ist (ein Linker-Fehler zu provozieren), oder ist ein Makro, das nicht kann nicht kompiliert, geändert werden, um Ihre aktuellen Vorlieben. Zum Beispiel, wenn Sie wollen etwas laufen, dass ist fertig, wollen Sie scheitern. Wenn Sie sich hinsetzen, um alle von ihnen loszuwerden, können Sie einen Compiler-Fehler werden soll.

Mit dem guten Code, den ich in der Regel tun:

void goodCode() {
     // TODO void goodCode()
     throw new NotSupportedOperationException("void goodCode()");
}

Mit dem Testcode in der Regel ich tun:

@Test
void testSomething() {
     // TODO void test Something
     Assert.assert("Some descriptive text about what to test")
}

Wenn JUnit verwenden, und wollen nicht den Fehler zu erhalten, aber den Fehler, dann in der Regel ich tun:

@Test
void testSomething() {
     // TODO void test Something
     throw new NotSupportedOperationException("Some descriptive text about what to test")
}

Beware Assert.Fail und seine verderblichen Einfluss auf Entwickler albern oder gebrochene Tests machen schreiben. Zum Beispiel:

[TestMethod]
public void TestWork()
{
    try {
        Work();
    }
    catch {
        Assert.Fail();
    }
}

Das ist dumm, weil das Try-Catch redundant ist. Ein Test schlägt fehl, wenn es eine Ausnahme auslöst.

Auch

[TestMethod]
public void TestDivide()
{
    try {
        Divide(5,0);
        Assert.Fail();
    } catch { }
}

Dies gebrochen ist, wird der Test immer passiert unabhängig vom Ergebnis der Divide-Funktion. Wieder ein Test fehlschlägt, wenn und nur wenn es eine Ausnahme auslöst.

Warum würden Sie Assert.Fail zu sagen, dass eine Ausnahme ausgelöst werden sollte? Das ist nicht notwendig. Warum nicht einfach das ExpectedException Attribut verwenden?

Wenn Sie einen Test schreiben, welcher sich gerade ausfällt, und dann den Code zu schreiben, dann den Test zu schreiben. Dieser Test ist nicht Driven Development.

Technisch Assert.fail () soll nicht erforderlich sein, wenn Sie richtig Test Driven Development mit sind.

Haben Sie gedacht, eine ToDo-Liste zu verwenden, oder eine GTD-Methode, um Ihre Arbeit anwenden?

MS Test hat Assert.Fail () , aber es hat auch Assert.Inconclusive () . Ich denke, dass die am besten geeignete Verwendung für Assert.Fail () ist, wenn Sie etwas in-line Logik haben, das unangenehm sein würde, in einer Behauptung zu setzen, auch wenn ich nicht einmal von jedem guten Beispiel denken. Für den größten Teil, wenn der Test-Framework etwas anderes als Assert.Fail unterstützt () dann verwenden.

Ich glaube, Sie sollten sich fragen, was (im Voraus) Tests sollten tun.

Zuerst schreiben Sie einen (Satz) Test ohne implmentation. Vielleicht auch die regnerischen Tag Szenarien.

diese Tests müssen alle, nicht korrekt Tests sein: Sie wollen also zwei Dinge erreichen: 1) Stellen Sie sicher, dass Ihre Implementierung korrekt ist; 2) Stellen Sie sicher, dass Ihre Unit-Tests korrekt sind.

Nun, wenn Sie im Voraus TDD tun, möchten Sie alle Ihre Tests auszuführen, auch die NYI Teile. Das Ergebnis Ihrer gesamten Testlauf passiert, wenn: 1) Alle implementiert Sachen erfolgreich 2) Alle NYI Sachen nicht

Schließlich wäre es ein Unit-Test ommision sein, wenn die Komponententests erfolgreich ist, während es keine Implementierung ist, es ist nicht?

Sie mögen mit etwas von einer Mail Ihres kontinuierlichen Integrationstest am Ende, dass alle implementierten Kontrollen und nicht-Code implementiert, und wird gesendet, wenn jeder implementiert Code fehlschlägt, oder ein nicht implementiert Code erfolgreich ist. Beide sind unerwünschte Ergebnisse.

Nur ein schreiben [ignore] Tests werden nicht die Arbeit machen. Weder ein behauptet, dass eine der ersten assert Ausfall stoppt, nicht andere Tests Linien im Test ausgeführt wird.

Nun, wie dies dann acheive? Ich denke, es ist etwas fortgeschritteneren Organisation Ihrer Tests erfordert. Und es erfordert ein anderer Mechanismus aktiviert dann diese Ziele zu erreichen.

Ich glaube, Sie Ihre Tests zu teilen haben und einige Tests erstellen, die vollständig ausgeführt werden müssen aber nicht, und umgekehrt.

Die Ideen sind Ihre Tests über mehrere Baugruppen aufgeteilt, Verwendung Gruppierung von Tests (geordnete Tests in mstest kann die Arbeit erledigen).

Noch ein CI-Build, die E-Mails, wenn nicht alle Tests in der NYI Abteilung scheitern, ist nicht einfach und unkompliziert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top