2017-03-06 6 views
4

Ich schreibe einige Komponententests in C# mit Nunit. Betrachten Sie den folgenden Code ein:Ist es eine schlechte Übung, Komponententests in einer Schleife auszuführen?

[Test()] 
    public void TestCarCost() { 
     for (int i = 0; i < Examples.exampleCount; i++) { 
      Car car = new Car(Examples[i]); 
      Assert.AreEqual (car.getCost(), Examples[i].cost, "Test " + (i + 1) + " failed"); 
     } 
    } 

Lassen Sie uns Beispiele sagen ist eine Klasse mit einigen statischen Daten für die Prüfung verschiedener möglicher Eingang für Fahrzeugtypen, wie man sehen kann ich für irgendwelche Fehler in der car.getCost zu testen, versuche() Funktion. Jetzt fühlt sich das in einer Schleife irgendwie falsch an, da zum Beispiel wenn eine der Behauptungen fehlschlägt, es dich immer zur selben Codezeile schickt. Außerdem, so weit ich weiß, wann immer eine Assert in [Test()] fehlschlägt, beendet nunit sofort den Rest des Testcodes. Was bedeutet, wenn ich alles innerhalb einer Schleife habe und behaupte, dass Nr 1 fehlschlägt, kann ich nicht sehen, ob der andere behauptet, dass es fehlgeschlagen ist. Das explizite Schreiben aller Tests schreibt im Wesentlichen kopierten Code, so dass es sich auch nicht richtig anfühlt. Was würde in dieser Situation als gute Praxis angesehen werden? Ist es in Ordnung, eine Menge ähnlichen Code im Komponententest zu haben? Gibt es eine elegante Lösung, die ich vermisse?

+2

Sie können hier das 'TestCase'-Attribut von NUnit verwenden. Was ist "Beispiel" hier? –

Antwort

5

Es ist besser, verwenden TestCaseAttribute statt Schleife. Bitte lesen Sie mehr über in folgenden .

In Ihrem Fall sollte sein:

[TestCase(1)] 
[TestCase(2)] 
[TestCase(3)] 
public void TestCarCost (int id) 
{   
    Car car = new Car(Examples[id]); 
    Assert.AreEqual (car.getCost(), Examples[id].cost, "Test " + (i + 1) + " failed"); 

} 

Hier können Sie mehrere Testfälle für die einzelnen Testverfahren erstellen. Für jeden Testfall können Sie einen Parameter im TestCase() Attribut angeben und als id an Ihre Testmethode übergeben.

Basierend auf id können Sie auf Ihre Ressourcen zugreifen, die in Ihrem Fall `Beispiele [ID] sind.

Ich werde lieber diesen Weg verwenden, weil ich jeden Fall überwachen kann und es keine zusätzliche Logik erfordert.

Auch wenn Sie zusätzliche Logik in einen Komponententest einfügen, erhöhen Sie die Wahrscheinlichkeit, dass Fehler auftreten, und Sie werden sich auf die Genauigkeit dieser Logik verlassen.

7

NUnit verfügt über eine integrierte Unterstützung für parameterized tests. Wenn Ihr Beispiel Daten einfach (dh Werte können in Attributen erscheinen, wie ein string), Ihr Test TestCase attributes und in etwa so aussehen verwenden:

[TestCase("Example Value 1", ExpectedResult=123.4)] 
[TestCase("Example Value 2", ExpectedResult=567.8)] 
[TestCase("Example Value 3", ExpectedResult=901.2)] 
public void TestCarCost (string exampleValue) { 
    Car car = new Car(exampleValue); 
    return car.GetCost();   
} 

Wenn Ihr Beispielwert (wirklich, Testeingang) nicht erscheint in Attribute, können Sie die TestCaseSource attribute, um anzuzeigen, ein Mitglied verwenden können, die die Werte für Sie liefern wird:

[TestCaseSource(nameof(Examples))] 
public void TestCarCost (ExampleInput exampleValue) { 
    Car car = new Car(exampleValue); 
    return car.GetCost();   
} 

public IEnumerable<ITestCaseData> Examples { 
    get { 
     yield return new TestCaseData(new ExampleInput(1,2)).Returns(123.4); 
     yield return new TestCaseData(new ExampleInput(3,4)).Returns(567.8); 
     yield return new TestCaseData(new ExampleInput(5,6)).Returns(901.2); 
    } 
} 
+0

Ich habe den anderen Beitrag angenommen, aber Ihre Antwort ist auch sehr aufschlussreich, danke. Es wird mir in Zukunft sicher nützlich sein. – TheMountainThatCodes

Verwandte Themen