Ich habe im Grunde das Wesentliche von TDD. Ich bin verkauft, dass es nützlich ist und ich habe ein vernünftiges Kommando über das MSTEST-Framework. Bisher war ich jedoch nicht in der Lage, es als primäre Entwicklungsmethode zu verwenden. Meistens verwende ich es als Ersatz für das Schreiben von Konsolen-Apps als Testtreiber (mein traditioneller Ansatz).
Das Nützlichste daran ist für mich, wie es die Rolle von Regressionstests aufnimmt.
Ich habe noch nichts gebaut, das speziell verschiedene testbare Verhaltensweisen isoliert, was ein weiterer großer Teil des Bildes ist, das ich kenne.
Diese Frage besteht also darin, nach Hinweisen zu fragen, welche ersten Tests ich für die folgende Entwicklungsaufgabe schreiben könnte: Ich möchte Code erstellen, der die Aufgabenausführung in der Art von Produzent / Verbraucher kapselt.
Ich hörte auf und beschloss, diese Frage zu schreiben, nachdem ich diesen Code geschrieben hatte (ich fragte mich, ob ich TDD diesmal tatsächlich verwenden könnte).
Code:
interface ITask
{
Guid TaskId { get; }
bool IsComplete { get; }
bool IsFailed { get; }
bool IsRunning { get; }
}
interface ITaskContainer
{
Guid AddTask(ICommand action);
}
interface ICommand
{
string CommandName { get; }
Dictionary<string, object> Parameters { get; }
void Execute();
}
Antworten:
Beginnen Sie mit diesem Konzept:
1) Beginnen Sie mit dem gewünschten Verhalten. Schreiben Sie einen Test dafür. Siehe Test fehlgeschlagen.
2) Schreiben Sie genügend Code, um den Test zu bestehen. Alle Tests bestehen.
3) Suchen Sie nach redundantem / schlampigem Code -> Refactor. Siehe Tests noch bestanden. Gehe zu 1
Nehmen wir also auf # 1 an, Sie möchten einen neuen Befehl erstellen (ich strecke mich danach, wie der Befehl funktionieren würde, also nehmen Sie ihn mit). (Außerdem bin ich eher ein bisschen pragmatisch als extrem TDD)
Der neue Befehl heißt MakeMyLunch. Sie erstellen also zuerst einen Test, um ihn zu instanziieren und den Befehlsnamen abzurufen:
Dies schlägt fehl und zwingt Sie, die neue Befehlsklasse zu erstellen und ihren Namen zurückzugeben (Purist würde sagen, dies sind zwei Runden TDD, nicht 1). Sie erstellen also die Klasse und lassen sie die ICommand-Schnittstelle implementieren, einschließlich der Rückgabe des Befehlsnamens. Wenn Sie jetzt alle Tests ausführen, werden alle Tests angezeigt. Suchen Sie daher nach Refactoring-Möglichkeiten. Wahrscheinlich keine.
Als nächstes möchten Sie, dass es execute implementiert. Sie müssen sich also fragen: Woher weiß ich, dass "MakeMyLunch" erfolgreich "mein Mittagessen zubereitet" hat? Welche Änderungen im System aufgrund dieser Operation? Kann ich das testen?
Angenommen, es ist einfach zu testen auf:
In anderen Fällen ist dies schwieriger, und Sie möchten wirklich die Verantwortlichkeiten des zu testenden Probanden testen (MakeMyLunchCommand). Möglicherweise liegt die Verantwortung von MakeMyLunchCommand in der Interaktion mit Kühlschrank und Mikrowelle. Um es zu testen, können Sie einen Scheinkühlschrank und eine Scheinmikrowelle verwenden. [Zwei Beispiel-Mock-Frameworks sind Mockito und nMock oder schauen Sie hier .]
In diesem Fall würden Sie so etwas wie den folgenden Pseudocode tun:
Der Purist sagt, testen Sie die Verantwortung Ihrer Klasse - ihre Interaktionen mit anderen Klassen (hat der Befehl den Kühlschrank geöffnet und die Mikrowelle eingeschaltet?).
Der Pragmatiker sagt Test für eine Gruppe von Klassen und Test für das Ergebnis (ist Ihr Mittagessen fertig?).
Finden Sie die richtige Balance, die für Ihr System funktioniert.
(Hinweis: Bedenken Sie, dass Sie möglicherweise zu früh zu Ihrer Schnittstellenstruktur gelangt sind. Vielleicht können Sie dies beim Schreiben Ihrer Komponententests und Implementierungen weiterentwickeln, und in Schritt 3 "bemerken" Sie die allgemeine Schnittstellenmöglichkeit.)
quelle