Azure Pipelines を使って .NET Standard (C#) のコードを自動テストする

Azure Pipelines とは?

Azure Pipelines とは、 Circle CI のように、 GitHub の Push などをトリガーにして自動的にビルド、テストを実行してくれるサービスです。 何よりも Microsoft のサービスである Azure DevOps のサービスであるため、 .NET と相性が良さそう! ということで使用してみました。

何よりも素晴らしいのが、 OSS プロジェクトであれば、 無制限 のビルド時間が使用できるということです。(並列に実行できるプロセス数には制限があります。)

今回行ったこと

GitHub 上で開発している Markdown パーサー のテストを自動化するために使用しました。 このリポジトリのソリューションには 2 つのプロジェクトがあり、

となっています。

プルリクを作成した時や master ブランチにマージした後に自動でトリガーが発火して自動ビルド、テストが走ります。

GitHub と接続すると、設定ファイルがリポジトリのルートディレクトリに azure-pipelines.yaml のファイル名で配置されるので、それを編集することで Azure Pipelines の動作を設定できます。

How to

予め、 Azure DevOps のアカウント、組織、プロジェクトを作成しておく必要があります。

その上で。 GitHub の market place から Azure Pipelines を適切なリポジトリにインストールし、認証を行います。認証などは、表示されるメッセージ等に従っていけば特に問題なく進めると思います。

最後に、ビルド、テストの方法を設定します。
今回は .NET Desktop をテンプレートとして選択しました。 これが初期状態での設定ファイルです。

trigger:
- master

pool:
  vmImage: 'VS2017-Win2016'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@0

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

しかし、この状態では正常にビルドできません。というのも、適切な .NET Core の SDK がインストールされていないらしく、テストプロジェクトがビルドできないようです。

2019-02-15T10:43:51.8072784Z ##[warning]TestProject\TestProject.csproj(0,0): Warning NU1604: Project dependency Microsoft.NETCore.App does not contain an inclusive lower bound. Include a lower bound in the dependency version to ensure consistent restore results.
2019-02-15T10:43:51.8083499Z D:\a\1\s\TestProject\TestProject.csproj : warning NU1604: Project dependency Microsoft.NETCore.App does not contain an inclusive lower bound. Include a lower bound in the dependency version to ensure consistent restore results.
2019-02-15T10:43:51.8365417Z ##[error]TestProject\TestProject.csproj(0,0): Error : NETSDK1061: The project was restored using Microsoft.NETCore.App version 1.0.0, but with current settings, version 2.1.0 would be used instead. To resolve this issue, make sure the same settings are used for restore and for subsequent operations such as build or publish. Typically this issue can occur if the RuntimeIdentifier property is set during build or publish but not during restore. For more information, see https://aka.ms/dotnet-runtime-patch-selection.

このようなエラー、警告が出ます。どうやら .NET Core のバージョンがおかしいようです。 そこで、 - task: NuGetToolInstaller@0 の次の行に以下のコードを追加し、 .NET Core の sdk を明示的にインストールするようにしました。

- task: DotNetCoreInstaller@0
  inputs:
    packageType: sdk
version: '2.1.300'

この修正でビルドはできるようになりましたが、次はテストの設定が必要です。
このテンプレートにはテストの対象となるアセンブリの設定がないので、追加します。

    vsTestVersion: "15.0"
    testAssemblyVer2: '**/bin/$(buildConfiguration)/**/TestProject.dll'

vsTestVersion では、 VS 2017 を使用してテストすることを明示的に指定しています。 (おそらく何も書かなくてもこの設定になると思われます。)
また、 testAssemblyVer2 では、テストの対象となるアセンブリを指定しています。
このとき、 .../obj/Relrease/.../....dll といったパスを対象にするとテストでエラーとなるので注意してください。 (obj に出てくるのは最終的なアセンブリではないため。)

これらの修正をした後に最終的に完成したのが、以下の yaml です。

この設定ファイルを使って、自動化がずいぶん捗ります!