Mit dem Aufkommen von .Net Core haben wir die großartige Gelegenheit, unseren Code nicht nur auf verschiedenen Betriebssystemen auszuführen, sondern auch auf verschiedenen Betriebssystemen zu testen. Und was könnte besser sein als Docker, wenn Sie mit einem anderen Betriebssystem arbeiten?

Testen ist wertvoller, wenn Sie keinen Unterschied zwischen der Testumgebung und den Zielumgebungen haben. Stellen Sie sich vor, Sie unterstützen Ihre Anwendung auf mehreren Betriebssystemen oder Versionen eines Betriebssystems. Mit Docker können Sie Ihre Anwendung in jedem von ihnen testen.
In diesem Artikel wird erläutert, wie Sie ein separates Image erstellen, in dem Komponententests Ihrer Anwendung gestartet und für die gesamte CI / CD-Pipeline in VSTS konfiguriert werden, bei der es sich kürzlich um Azure DevOps handelt.
Wenn Sie mit Docker arbeiten, verwenden Sie wahrscheinlich mehrstufige Builds, um Ihre Container zu erstellen. In diesem Fall kombinieren Sie die Erstellung von Binärdateien (mithilfe des Build-Images) und die Erstellung des endgültigen Images (mithilfe des Laufzeit-Images) in derselben Docker-Datei.
Wenn Ihr System aus einem Container besteht, besteht in diesem Fall der häufigste Ansatz darin, Tests als Teil des Prozesses zum Erstellen des endgültigen Images auszuführen. Das heißt, Tests in der Docker-Datei ausführen.
Um dies in einem mehrstufigen Prozess zu tun, führen Sie beim Starten von
docker build
die Tests als weiteren Schritt zum
docker build
des endgültigen Images aus. Schauen wir uns ein einfaches Beispiel an. Angenommen, wir haben zwei Projekte: Webanwendungen und Komponententests:
Machen wir uns vorerst keine Gedanken darüber, was die Webanwendung tut. Auf der anderen Seite haben wir den einzigen Test, der das Verhalten von
GuidProvider
und so aussieht:
[Fact] public void Never_return_a_empty_guid() {
Erstellen Sie nun eine Docker-Datei, die das WebApplication-Image erstellt und gleichzeitig die Tests ausführt:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY CiCd.sln . COPY WebApplication/WebApplication.csproj WebApplication/ COPY WebApplication.Test/WebApplication.Test.csproj WebApplication.Test/ RUN dotnet restore COPY . . WORKDIR /src/WebApplication RUN dotnet build --no-restore -c Release -o /app FROM build as test WORKDIR /src/WebApplication.Test RUN dotnet test FROM build AS publish WORKDIR /src/WebApplication RUN dotnet publish --no-build -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "WebApplication.dll"]
Diese Docker-Datei muss in einem Verzeichnis mit einer Lösungsdatei (iCd.sln) abgelegt werden. Verwenden Sie den folgenden Befehl, um ein Bild zu erstellen:
docker build -t webapplication .
Unser Test schlägt fehl (ein Fehler in
GuidProvider
, der immer
Guid.Empty
), sodass der Image-Build fehlschlägt:
Ausgabe Step 15/22 : RUN dotnet test ---> Running in 423c27696356 Build started, please wait... Build completed. Test run for /src/WebApplication.Test/bin/Debug/netcoreapp2.1/WebApplication.Test.dll(.NETCoreApp,Version=v2.1) Microsoft (R) Test Execution Command Line Tool Version 15.9.0 Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... [xUnit.net 00:00:00.96] WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid [FAIL] Failed WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid Error Message: Assert.NotEqual() Failure Expected: Not 00000000-0000-0000-0000-000000000000 Actual: 00000000-0000-0000-0000-000000000000 Stack Trace: at WebApplication.Test.GuidProviderTests.Never_return_a_empty_guid() in /src/WebApplication.Test/GuidProviderTests.cs:line 17 Test Run Failed. Total tests: 1. Passed: 0. Failed: 1. Skipped: 0. Test execution time: 2.8166 Seconds The command '/bin/sh -c dotnet test' returned a non-zero code: 1
Lassen Sie uns nun sehen, wie Sie diesen Prozess in Azure DevOps starten.
Unsere Build-Definition ist derzeit eine Aufgabe vom Typ Docker:

Infolge des Starts schlägt der Build fehl, weil unser Test abfällt. Außerdem haben wir keine Testergebnisse (die Registerkarte "Test" ist leer), da nach dem Verständnis von VSTS keine Tests durchgeführt werden:

Das Ausführen von Tests als Teil einer Image-Assembly ist nicht ganz schlecht, verhindert jedoch, dass VSTS weiß, was das Ergebnis war. Dies liegt an der „Einschränkung“ von Docker, die das Erstellen von Volumes während des
docker build
dotnet test
nicht zulässt. Daher können wir keine Datei mit Testergebnissen bereitstellen (die mit dem
dotnet test
generiert werden
dotnet test
). Diese Datei verbleibt in einem Zwischencontainer und kann nicht einfach
dotnet test
ihn von dort.
Wir werden einen anderen Ansatz
docker run
und eine großartige Alternative zum
docker run
. Lassen Sie uns zunächst einen separaten Container anheben und die Tests darin ausführen. Für beide Container können wir dasselbe Dockerfile verwenden. Zunächst müssen wir die Zeile, in der der
dotnet test
aus der Docker-
dotnet test
entfernen, da wir sie jetzt separat ausführen werden. Ok, jetzt verwenden wir den
docker run
, mit dem Sie die
docker run
Datei bis zu einem bestimmten Punkt ausführen können. In unserem Fall ist dies die Testphase:
docker build -t webapplication-tests . --target test
Der Parameter
-target
gibt an, welche Stufe zusammengesetzt werden soll. Bitte beachten Sie, dass das generierte Bild als "
Webanwendungstests " bezeichnet wird. Jetzt können wir unsere Tests ausführen und die Datei "
test-results.trx " mit den Ergebnissen ihrer Ausführung im Containerverzeichnis "
tests " speichern:
docker run -v/c/tests:/tests webapplication-tests --entrypoint "dotnet test --logger trx;LogFileName=/tests/test-results.trx"
Hier führen wir das im vorherigen Schritt erstellte Image aus und ordnen dadurch das Containerverzeichnis "
tests " dem Hostverzeichnis zu (in meinem Fall D: \ CiCD \ tests). Als Ergebnis habe ich Testergebnisse in D: \ CiCD \ tests erhalten.
Führen Sie Folgendes aus, um das endgültige Image zu erstellen:
docker build -t webapplication .
Der Vorteil besteht darin, dass dank des Docker-Level-Modells nicht alle anderen Schritte erneut ausgeführt werden müssen (d. H. Die Anwendung muss nicht neu kompiliert werden).
Wenden wir dies nun auf Azure DevOps-Pipelines an. Um die Montage zu vereinfachen und eine große Anzahl von Parametern zu vermeiden, verwenden wir Docker-Compose. Unsere docker-compose.yml hat folgenden Inhalt:
version: '3.5' services: webapplication: image: webapplication build: context: . dockerfile: Dockerfile webapplication-tests: image: webapplication-tests build: context: . dockerfile: Dockerfile target: test
Hier definieren wir zwei Bilder (Webanwendung und Webanwendungstests). Damit alles dem Kanon entspricht, fügen wir die Datei docker-compose.override.yml hinzu:
version: '3.5' services: webapplication: environment: - ASPNETCORE_ENVIRONMENT=Development ports: - "8080:80" webapplication-tests: entrypoint: - dotnet - test - --logger - trx;LogFileName=/tests/test-results.trx volumes: - ${BUILD_ARTIFACTSTAGINGDIRECTORY:-./tests/}:/tests
Großartig, jetzt, um die Tests durchzuführen, müssen wir nur noch:
docker-compose run webapplication-tests
Dieser Befehl führt die Tests aus und erstellt die Ausgabe-TRX-Datei in dem Verzeichnis, das durch die Umgebungsvariable
BUILD_ARTIFACTSTAGINGDIRECTORY
oder es wird der Standardwert
./tests
. Das endgültige Bild sieht folgendermaßen aus:
docker-compose build webapplication
Jetzt können Sie unseren CI-Prozess in Azure DevOps bearbeiten. Dazu definieren wir folgende Schritte:
- Sammle alle Bilder [build]
- Unit-Tests ausführen [ausführen]
- Testergebnis veröffentlichen [veröffentlichen]
- Führen Sie Bilder im Repository (Registrierung) aus [push]
Beginnen wir mit dem ersten Schritt, der Docker Compose-Aufgabe (Task) in Azure:

Wir setzen
Action: Build service images
und geben Sie den Pfad zu docker-compose.yml an.
Führen Sie als Nächstes den Container mit Komponententests aus:

Hier müssen Sie
Action: Run a specific service image
auswählen
Action: Run a specific service image
und geben Sie den Containernamen an.
Service Name: webapplication-tests
. Vergessen Sie auch nicht den Pfad zu docker-compose.yml und docker-compose.override.yml. Der Wert für
Run in Background
sollte nicht festgelegt werden, da sonst der Container im "Detached Mode" gestartet wird und die Task nicht auf die Ergebnisse der Tests wartet und mit dem nächsten Schritt fortfährt. Die Aufgabe Testergebnisse veröffentlichen versucht, Ergebnisse zu veröffentlichen, die möglicherweise noch nicht verfügbar sind, da das Ausführen von Tests einige Zeit in Anspruch nimmt.
Der dritte Schritt ist "Testergebnisse veröffentlichen":
Es ist wichtig anzugeben,
Run this task: Even if a previous task has failed, unless the build was canceled
. Diese Option ist wichtig, da sonst die Ergebnisse niemals veröffentlicht werden, wenn die Tests fehlschlagen.
Search folder: $(Build.ArtifactStagingDirectory)
Der letzte Schritt besteht darin, die Bilder in den Speicher zu verschieben. Geben Sie dazu das Azure-Abonnement sowie die Azure-Containerregistrierung an. Alles ist bereit, um einen neuen Build zu erstellen. Speichern. Wir fangen an. Wenn die Tests fehlschlagen, schlägt der Build fehl, aber jetzt sehen wir die Ergebnisse in VSTS:

Ich hoffe dieses Material war hilfreich. Sie finden meine Assembly-Konfigurations-XML-Datei
hier .
Vielen Dank für Ihre Aufmerksamkeit!