.Net Coreの登場により、異なるOSでコードを実行するだけでなく、異なるOSでテストする素晴らしい機会があります。 また、異なるOSで作業する場合、Dockerよりも優れているものはありますか?

テスト環境とターゲット環境に違いがない場合、テストはより価値があります。 複数のオペレーティングシステムまたはオペレーティングシステムのバージョンでアプリケーションをサポートするとします。 Dockerを使用すると、それぞれでアプリケーションをテストできます。
この記事では、アプリケーションの単体テストを起動する別のイメージを作成し、最近Azure DevOpsであるVSTSのこのすべてのCI / CDパイプラインを構成する方法について説明します。
Dockerを使用している場合、おそらくマルチステージビルドを使用してコンテナーをビルドしていることになります。 この場合、同じDockerファイル内でバイナリの作成(ビルドイメージを使用)と最終イメージ(ランタイムイメージを使用)の作成を組み合わせます。
システムが1つのコンテナで構成されている場合、この場合の最も一般的なアプローチは、最終イメージを構築するプロセスの一部としてテストを実行することです。 つまり、Dockerfileでテストを実行します。
マルチステッププロセスでこれを行うには、
docker build
を実行するときに、最終イメージをビルドする別のステップとしてテストを実行します。 簡単な例を見てみましょう。 Webアプリケーションと単体テストの2つのプロジェクトがあるとします。
今のところ、Webアプリケーションが何をするか心配する必要はありません。 一方、
GuidProvider
の動作を確認する唯一のテストは次のようになります。
[Fact] public void Never_return_a_empty_guid() {
次に、WebApplicationイメージを作成すると同時にテストを実行するDockerfileを作成します。
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"]
このDockerfileは、ソリューションファイル(iCd.sln)を含むディレクトリに配置する必要があります。 イメージを作成するには、次のコマンドを使用します。
docker build -t webapplication .
テストが失敗する(常に
GuidProvider
を返す
Guid.Empty
)ため、イメージのビルドは失敗します。
出力 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
では、Azure DevOpsでこのプロセスを開始する方法を見てみましょう。
現時点でのビルド定義は、Dockerタイプのタスクの1つです。

起動の結果、テストが失敗するため、ビルドは失敗します。 さらに、VSTSの理解ではテストが実行されないため、テスト結果はありません([テスト]タブは空です)。

イメージアセンブリの一部としてテストを実行することは完全に悪いことではありませんが、VSTSが実行の結果を知ることを防ぎます。 これは、Dockerの
docker build
中にボリュームを作成できないDockerの「制限」によるものです。したがって、テスト結果(
dotnet test
を使用して生成可能)をファイルに提供できません。このファイルは中間コンテナーに残り、簡単に取得できませんそこから彼。
別のアプローチを採用し、
docker run
優れた代替手段を使用し
docker run
。 最初に別のコンテナを作成し、そのコンテナでテストを実行します。 両方のコンテナに対して、同じDockerfileを使用できます。 まず、
dotnet test
を実行する行をDockerfileから削除する必要があります。これは、これらを個別に実行するためです。 では、dockerrun
docker run
を使用して、Dockerfileを特定のポイントまで実行できるようにします。 私たちの場合、これはテスト段階です:
docker build -t webapplication-tests . --target test
-target
パラメーターは、アセンブルするステージを示します。 生成された画像は「
webapplication-tests 」と呼ばれることに注意してください。 これで、テストを実行して、ファイル「
test-results.trx 」を実行結果とともにコンテナー「
tests 」ディレクトリに保存できます。
docker run -v/c/tests:/tests webapplication-tests --entrypoint "dotnet test --logger trx;LogFileName=/tests/test-results.trx"
ここで、前のステップで作成されたイメージを実行し、それによってコンテナ「
tests 」ディレクトリをホストディレクトリにマッピングします(私の場合はD:\ CiCD \ tests) その結果、D:\ CiCD \ testsでテスト結果が得られました。
最終的なイメージを構築するには、次を実行します:
docker build -t webapplication .
利点は、Dockerレベルモデルのおかげで、他のすべての手順を再実行する必要がないことです(つまり、アプリケーションを再コンパイルする必要がありません)。
それでは、このすべてをAzure DevOpsパイプラインに適用しましょう。 アセンブリを単純化し、多数のパラメーターを避けるために、docker-composeを使用します。 docker-compose.ymlのコンテンツは次のとおりです。
version: '3.5' services: webapplication: image: webapplication build: context: . dockerfile: Dockerfile webapplication-tests: image: webapplication-tests build: context: . dockerfile: Dockerfile target: test
ここでは、2つの画像(webapplicationとwebapplication-tests)を定義します。 すべてがキヤノンに従っているように、docker-compose.override.ymlファイルを追加しましょう:
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
素晴らしい、今テストを実行するために必要なことは:
docker-compose run webapplication-tests
このコマンドはテストを開始し、環境変数
BUILD_ARTIFACTSTAGINGDIRECTORY
指定されたディレクトリに出力trxファイルを作成するか、デフォルト値
./tests
ます。 最終的なイメージは次のようになります。
docker-compose build webapplication
これで、Azure DevOpsでCIプロセスを編集できます。 これを行うには、次の手順を定義します。
- すべてのイメージを収集[ビルド]
- 単体テストの実行[実行]
- テスト結果の公開[公開]
- リポジトリでのイメージの実行(レジストリ)[プッシュ]
AzureのDocker Composeタスク(タスク)である最初のステップから始めましょう。

Action: Build service images
を指定し、docker-compose.ymlへのパスを指定します。
次に、単体テストでコンテナを実行します。

ここで、[
Action: Run a specific service image
を
Action: Run a specific service image
を選択し、コンテナ名[
Service Name: webapplication-tests
を指定する必要があります。 また、docker-compose.ymlおよびdocker-compose.override.ymlへのパスを忘れないでください。
Run in Background
で
Run in Background
の値は設定しないでください。設定しないと、コンテナは「分離モード」で起動し、タスクはテストの結果を待たずに次のステップに進みます。 テストの実行には時間がかかるため、テスト結果の公開タスクは、まだ利用できない可能性のある結果を公開しようとします。
3番目のステップは「テスト結果の公開」です。
[ Run this task: Even if a previous task has failed, unless the build was canceled
を
Run this task: Even if a previous task has failed, unless the build was canceled
する]を指定する
ことが重要です Run this task: Even if a previous task has failed, unless the build was canceled
。 そうしないと、テストが失敗した場合に結果が公開されないため、このオプションは重要です。
Search folder: $(Build.ArtifactStagingDirectory)
最後のステップは、イメージをストレージにプッシュすることです。 これを行うには、AzureサブスクリプションとAzure Container Registryを指定します。 すべてが新しいビルドを作成する準備ができています。 保存します。 始めます。 テストが失敗すると、ビルドは失敗しますが、VSTSに結果が表示されます。

この資料がお役に立てば幸いです。
ここでアセンブリ構成を含む私のymlファイルを見つけることができます。
ご清聴ありがとうございました!