Erstens, Entschuldigung für den Titel, ich konnte mir nicht vorstellen, wie ich es am einfachsten erklären könnte!
Ich habe eine Methode, für die ich Komponententests schreiben möchte. Ich werde es ziemlich allgemein halten, da ich nicht auf die Implementierung der Methode, sondern nur auf das Testen derselben eingehen möchte. Die Methode ist:
public void HandleItem(item a)
{
CreateNewItem();
UpdateStatusOnPreviousItem();
SetNextRunDate();
}
Diese Klasse hat also eine öffentliche Methode, die dann einige private Methoden aufruft, um die Logik auszuführen.
Wenn ich den Unit-Test schreibe, möchte ich überprüfen, ob alle drei Dinge erledigt wurden. Da sie alle im selben Lauf aufgerufen werden, dachte ich, dass ich es als einen Test machen könnte:
public void GivenItem_WhenRun_Thenxxxxx
{
HandleItem(item);
// Assert item has been created
// Assert status has been set on the previous item
// Assert run date has been set
}
Aber ich dachte, ich könnte es auch als drei separate Tests schreiben:
public void GivenItem_WhenRun_ThenItemIsCreated()
{
HandleItem(item);
}
public void GivenItem_WhenRun_ThenStatusIsUpdatedOnPreviousItem()
{
HandleItem(item);
}
public void GivenItem_WhenRun_ThenRunDateIsSet()
{
HandleItem(item);
}
Das scheint mir besser zu sein, da es sich im Wesentlichen um eine Auflistung der Anforderungen handelt, aber dann hängen alle drei zusammen und erfordern genau die gleiche Arbeit, die mit der getesteten Methode ausgeführt wurde. Daher muss derselbe Code dreimal ausgeführt werden.
Gibt es einen empfohlenen Ansatz dafür?
Vielen Dank
quelle
Kurze Antwort: Es ist viel wichtiger, dass Ihre Tests alle Funktionen abdecken, als wie sie es tun.
Längere Antwort: Wenn Sie immer noch zwischen diesen weitgehend gleichwertigen Lösungen wählen möchten, können Sie zusätzliche Kriterien für das Beste verwenden. Zum Beispiel,
quelle
Verwenden Sie einen Methodenaufruf mit mehreren Zusicherungen. Hier ist der Grund:
Wenn Sie HandleItem (a) testen, testen Sie, dass die Methode das Element in den richtigen Zustand versetzt hat. Stellen Sie sich statt "eine Aussage pro Test" "ein logisches Konzept pro Test" vor.
Frage: Wenn ein CreateNewItem fehlschlägt, die beiden anderen Methoden jedoch erfolgreich sind, bedeutet dies, dass HandleItem erfolgreich abgeschlossen wurde? Ich vermute nicht.
Mit mehreren Zusicherungen (mit entsprechenden Meldungen) wissen Sie genau, was fehlgeschlagen ist. In der Regel testen Sie eine Methode mehrmals auf mehrere Eingaben oder Eingabezustände, um mehrere Zusicherungen nicht zu vermeiden.
IMO, diese Fragen sind in der Regel ein Zeichen für etwas anderes. Es ist ein Zeichen dafür, dass HandleItem nicht wirklich ein "Unit-Test" ist, da es nur an andere Methoden zu delegieren scheint. Wenn Sie einfach überprüfen, ob HandleItem andere Methoden korrekt aufruft, wird es eher zu einem Integrationstestkandidaten (in diesem Fall hätten Sie noch 3 Asserts).
Möglicherweise möchten Sie die anderen 3 Methoden veröffentlichen und unabhängig testen. Oder sie sogar in eine andere Klasse extrahieren.
quelle
Verwenden Sie den 2. Ansatz. Wenn der Test bei Ihrem ersten Ansatz fehlschlägt, wissen Sie nicht sofort, warum. Dies könnte eine der drei Funktionen sein, die fehlgeschlagen sind. Mit dem zweiten Ansatz wissen Sie sofort, wo das Problem aufgetreten ist. Sie können doppelten Code in Ihre Test-Setup-Funktion einfügen.
quelle
IMHO sollten Sie die drei Teile dieser Methode separat testen, damit Sie genauer wissen, wo Probleme auftreten, wenn sie auftreten, und dabei vermeiden, denselben Teil Ihres Codes zweimal zu überprüfen.
quelle
Ich glaube nicht, dass es ein gutes Argument dafür gibt, separate Testmethoden für Ihren Anwendungsfall zu schreiben. Wenn Sie die Ergebnisse aller drei variablen Bedingungen erhalten möchten, können Sie alle drei Bedingungen testen und ihre Fehler ausdrucken, indem Sie sie in a verketten
string
und feststellen, ob die Zeichenfolge nach Abschluss des Tests noch leer ist. Indem Sie alle in derselben Methode belassen, dokumentieren Ihre Bedingungen und Fehlermeldungen die erwartete Nachbedingung der Methode an einem Ort, anstatt sie in drei Methoden aufzuteilen, die später möglicherweise getrennt werden.Dies bedeutet, dass Ihr einzelner Test mehr Code enthält. Wenn Sie jedoch so viele Nachbedingungen haben, dass dies ein Problem darstellt, möchten Sie wahrscheinlich Ihre Testmethoden überarbeiten, um einzelne darin enthaltene Methoden zu testen
HandleItem
.quelle