Übung: Beheben eines fehlgeschlagenen Tests
Nun können Sie Komponententests ausführen, während Änderungen ihren Weg durch die Buildpipeline nehmen. Sie verfügen auch über eine Möglichkeit, zu messen, wie viel Code von Ihren Tests abgedeckt wird.
Es empfiehlt sich, dass Sie Ihre Tests lokal ausführen, bevor Sie Änderungen an die Pipeline übermitteln. Aber was passiert, wenn das jemand vergisst und eine Änderung übermittelt, die den Build beschädigt?
In dieser Lerneinheit korrigieren Sie einen fehlerhaften Build, der durch einen nicht bestandenen Komponententest verursacht wurde. Hierzu gehen Sie wie folgt vor:
- Abrufen des Startercodes von GitHub
- Hinzufügen von Code Coverage-Tools zum Projekt
- Übertragen des Codes mithilfe von Push an Ihr Repository
- Automatische Ausführung der Pipeline und Fehlschlagen der Komponententests
- Lokales Reproduzieren des Fehlers
- Analysieren und Beheben des Fehlers
- Übertragen einer Fehlerbehebung mithilfe von Push und erfolgreicher Build
Überprüfen des neuen Komponententests
Das neueste Feature des Teams umfasst die Bestenliste. Wir müssen die Punktezahl aus der Datenbank abrufen, sodass wir einen Komponententest schreiben können, um die IDocumentDBRepository<T>.GetItemsAsync
-Methode zu überprüfen.
Der Test sieht wie folgt aus. Sie müssen jetzt noch keinen Code hinzufügen.
[TestCase(0, ExpectedResult=0)]
[TestCase(1, ExpectedResult=1)]
[TestCase(10, ExpectedResult=10)]
public int ReturnRequestedCount(int count)
{
const int PAGE = 0; // take the first page of results
// Fetch the scores.
Task<IEnumerable<Score>> scoresTask = _scoreRepository.GetItemsAsync(
score => true, // return all scores
score => 1, // we don't care about the order
PAGE,
count // fetch this number of results
);
IEnumerable<Score> scores = scoresTask.Result;
// Verify that we received the specified number of items.
return scores.Count();
}
Denken Sie daran, dass TestCase
in einem NUnit-Test Inlinedaten zum Testen der betreffenden Methode bereitstellt. NUnit ruft die Komponententestmethode ReturnRequestedCount
folgendermaßen auf:
ReturnRequestedCount(0);
ReturnRequestedCount(1);
ReturnRequestedCount(10);
Dieser Test verwendet auch die ExpectedResult
-Eigenschaft, um den Testcode zu vereinfachen und die Testabsicht zu verdeutlichen. NUnit vergleicht den Rückgabewert automatisch mit dem Wert dieser Eigenschaft, sodass die Assert-Anweisung nicht explizit aufgerufen werden muss.
Wir wählen einige Werte aus, die typische Abfragen darstellen. Wir schließen auch 0 ein, um diesen Grenzfall abzudecken.
Abrufen des Branchs aus GitHub
Wie zuvor rufen Sie den Branch failed-test
aus GitHub ab und checken ihn aus oder wechseln zu ihm.
Öffnen Sie in Visual Studio Code das integrierte Terminal.
Führen Sie die folgenden
git fetch
- undgit checkout
-Befehle aus, um einen Branch namensfailed-test
aus dem Microsoft-Repository herunterzuladen, und wechseln Sie zu diesem Branch:git fetch upstream failed-test git checkout -B failed-test upstream/failed-test
Für diese Übung haben wir den Branch
failed-test
genannt. In der Praxis würden Sie ein Branch dem Zweck oder Feature entsprechend benennen.Führen Sie die folgenden Befehle aus, um eine lokale Toolmanifestdatei zu erstellen, das
ReportGenerator
-Tool zu installieren und dascoverlet.msbuild
-Paket zum Testprojekt hinzuzufügen:dotnet new tool-manifest dotnet tool install dotnet-reportgenerator-globaltool dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
Dieser Schritt ist erforderlich, weil der Branch
failed-test
nicht die Arbeit enthält, die Sie dem Branchunit-tests
hinzugefügt haben.Fügen Sie die Testprojektdatei und die Toolmanifestdatei zum Stagingindex hinzu, und committen Sie die Änderungen.
git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git add .config/dotnet-tools.json git commit -m "Configure code coverage tests"
Führen Sie den folgenden
git push
-Befehl aus, um den Branchfailed-test
in Ihr GitHub-Repository hochzuladen:git push origin failed-test
Anzeigen des Testfehlschlags in der Pipeline
Angenommen, Sie waren in Eile und haben Ihre Arbeit gepusht, ohne die Tests ein letztes Mal durchzuführen. Glücklicherweise kann die Pipeline Ihnen helfen, Probleme frühzeitig abzufangen, wenn Komponententests vorhanden sind. Das werden wir Ihnen hier zeigen.
Verfolgen Sie in Azure Pipelines den Build, wenn er die Pipeline durchläuft.
Erweitern Sie die Aufgabe Run unit tests - Release, während sie ausgeführt wird.
Sie sehen, dass die
ReturnRequestedCount
-Testmethode fehlschlägt.Der Test wird bestanden, wenn der Eingabewert 0 ist, schlägt aber fehl, wenn der Eingabe Wert 1 oder 10 ist.
Der Build wird erst dann in der Pipeline veröffentlicht, wenn die vorherige Aufgabe erfolgreich durchgeführt wurde. Hier wurde der Build nicht veröffentlicht, weil die Komponententests fehlgeschlagen sind. Dadurch wird verhindert, dass andere versehentlich einen fehlerhaften Build erhalten.
In der Praxis werden Sie den Build während der Ausführung nicht immer manuell nachverfolgen. Nachstehend sind einige Möglichkeiten aufgeführt, wie der Fehler erkannt werden kann:
E-Mail-Benachrichtigung von Azure DevOps
Sie können Azure DevOps so konfigurieren, dass eine E-Mail-Benachrichtigung gesendet wird, wenn der Build beendet ist. Die Betreffzeile beginnt mit "[Build failed]", wenn der Build fehlschlägt.
Azure Test Plans
Wählen Sie in Azure DevOps Test Plans und dann Runs aus. Die letzten Testläufe, einschließlich des soeben ausgeführten Testlaufs, werden angezeigt. Wählen Sie den letzten abgeschlossenen Test aus. Sie sehen, dass zwei der acht Tests fehlgeschlagen sind.
Das Dashboard
Wählen Sie in Azure DevOps Overview und dann Dashboards aus. Der Fehler wird im Widget Test Results Trend angezeigt. Das Code Coverage-Widget ist leer, was darauf hinweist, dass kein Code Coverage-Test ausgeführt wurde.
Der Build-Badge
Obwohl der
failed-test
-Branch keinen Build-Badge in der README.md-Datei enthält, würde auf GitHub Folgendes angezeigt, wenn der Build fehlschlägt:
Analysieren des Testfehler
Wenn Komponententests fehlschlagen, haben Sie je nach Fehler normalerweise zwei Möglichkeiten:
- Wenn der Test einen Fehler im Code aufzeigt, korrigieren Sie den Code und führen die Tests erneut aus.
- Wenn sich die Funktionalität geändert hat, passen Sie den Test so an, dass er den neuen Anforderungen entspricht.
Lokales Reproduzieren des Fehlers
In diesem Abschnitt reproduzieren Sie den Fehler lokal.
Öffnen Sie in Visual Studio Code das integrierte Terminal.
Führen Sie im Terminal diesen
dotnet build
-Befehl aus, um die Anwendung zu kompilieren:dotnet build --configuration Release
Führen Sie im Terminal diesen
dotnet test
-Befehl aus, um die Komponententests auszuführen:dotnet test --no-build --configuration Release
Ihnen sollten dieselben Fehler angezeigt werden, die auch in der Pipeline angezeigt wurden. Hier sehen Sie einen Teil der Ausgabe:
Starting test execution, please wait... A total of 1 test files matched the specified pattern. Failed ReturnRequestedCount(1) [33 ms] Error Message: Expected: 1 But was: 0 Stack Trace: at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context) at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0() at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action) Failed ReturnRequestedCount(10) [1 ms] Error Message: Expected: 10 But was: 9 Stack Trace: at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context) at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0() at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action) Failed! - Failed: 2, Passed: 6, Skipped: 0, Total: 8, Duration: 98 ms
Suchen der Fehlerursache
Sie bemerken, dass jeder fehlgeschlagene Test ein um eins abweichendes Ergebnis erzeugt. Wenn z. B. 10 erwartet wird, gibt der Test 9 zurück.
Sie sehen sich den Quellcode für die getestete Methode LocalDocumentDBRepository<T>.GetItemsAsync
an. Folgendes sollte angezeigt werden:
public Task<IEnumerable<T>> GetItemsAsync(
Func<T, bool> queryPredicate,
Func<T, int> orderDescendingPredicate,
int page = 1, int pageSize = 10
)
{
var result = _items
.Where(queryPredicate) // filter
.OrderByDescending(orderDescendingPredicate) // sort
.Skip(page * pageSize) // find page
.Take(pageSize - 1); // take items
return Task<IEnumerable<T>>.FromResult(result);
}
In diesem Szenario könnten Sie GitHub überprüfen, um zu nachzusehen, ob die Datei kürzlich geändert wurde.
Sie vermuten, dass pageSize - 1
ein um eins kleineres Ergebnis zurückgibt und der Code lediglich pageSize
lauten sollte. In unserem Szenario ist dies ein Fehler, den Sie beim Pushen ohne Tests ausgeführt haben, aber in einem realen Szenario können Sie sich bei dem Entwickler erkundigen, der die Datei auf GitHub geändert hat, um den Grund für die Änderung zu ermitteln.
Tipp
Diskussion und Zusammenarbeit sind auch auf GitHub möglich. Sie können einen Pull Request kommentieren oder eine Problemdiskussion eröffnen.
Beheben des Fehlers
In diesem Abschnitt beheben Sie den Fehler, indem Sie den Code wieder in seinen ursprünglichen Zustand zurück versetzen und die Tests ausführen, um die Korrektur zu überprüfen.
Öffnen Sie in Visual Studio Code Tailspin.SpaceGame.Web/LocalDocumentDBRepository.cs im Datei-Explorer.
Ändern Sie die
GetItemsAsync
-Methode wie hier gezeigt:public Task<IEnumerable<T>> GetItemsAsync( Func<T, bool> queryPredicate, Func<T, int> orderDescendingPredicate, int page = 1, int pageSize = 10 ) { var result = _items .Where(queryPredicate) // filter .OrderByDescending(orderDescendingPredicate) // sort .Skip(page * pageSize) // find page .Take(pageSize); // take items return Task<IEnumerable<T>>.FromResult(result); }
Diese Version ändert
pageSize - 1
inpageSize
.Speichern Sie die Datei .
Kompilieren Sie die Anwendung im integrierten Terminal.
dotnet build --configuration Release
Sie sollten sehen, dass der Build erfolgreich ist.
In der Praxis können Sie die App ausführen und kurz ausprobieren. Im Rahmen dieser Übung verzichten wir darauf.
Führen Sie die Komponententests im Terminal aus.
dotnet test --no-build --configuration Release
Sie sehen, dass die Tests erfolgreich durchgeführt werden.
Starting test execution, please wait... A total of 1 test files matched the specified pattern. Passed! - Failed: 0, Passed: 8, Skipped: 0, Total: 8, Duration: 69 ms
Fügen Sie alle geänderten Dateien im integrierten Terminal zum Index hinzu, committen Sie die Änderungen, und pushen Sie den Branch an GitHub.
git add . git commit -m "Return correct number of items" git push origin failed-test
Tipp
Der Punkt (
.
) in diesemgit add
-Beispiel ist ein Platzhalterzeichen. Er steht für alle ungestageten Dateien im aktuellen Verzeichnis und allen Unterverzeichnissen.Bevor Sie dieses Platzhalterzeichen verwenden, sollten Sie
git status
ausführen bevor sich sich festlegen, um sicherzustellen, dass Sie die tatsächlich die gewünschten Dateien stagen.Kehren Sie zu Azure Pipelines zurück. Beobachten Sie, wie die Änderung die Pipeline durchläuft. Die Tests werden bestanden, und der gesamte Buildvorgang ist erfolgreich.
Zum Überprüfen der Testergebnisse können Sie optional die Registerkarten Tests und Code Coverage auswählen, nachdem der Buildvorgang abgeschlossen wurde.
Sie können den aktualisierten Ergebnistrend auch im Dashboard überprüfen.
Großartig! Sie haben den Build korrigiert. Als Nächstes erfahren Sie, wie Sie Ihre Azure DevOps-Umgebung bereinigen.