C++でGoogle Testを利用したWindowsアプリケーションのCI

# はじめに

(2019年7月現在)

Windows (特にVisual Studio)で開発をしているソフトウェアのUnit TestのCIを回すには、当たり前だがWindows環境が必要である。[^1]
つまり、WindowsとVisual StudioがインストールされたVMが必要である。Windowsを無料で使える環境を準備してくれているCIサービスはいくつかある[^2]が、その中でもVisual StudioのC++コンパイラをプライベートレポジトリに対して利用できるサービスは、ライセンス料の観点からか、Microsoftの[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/)中の[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)くらいしか見つけられなかった。[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)では同時実行1で月間30時間まで無料で使えます[^3]。

[^1]: ビルドツールである[MSBuild](https://docs.microsoft.com/ja-jp/visualstudio/msbuild/msbuild?view=vs-2019)は無償で使えるし、Clangを利用すれば正確にはVisual Studioのライセンスを利用する必要はないはずだが、まだ未テストである。
[^2]: 2019年7月現在、[Travis CI](https://travis-ci.org/)はC++コンパイラがないし、[AppVeyor](https://www.appveyor.com/)は非オープンソースでは有料になる。
[^3]: https://docs.microsoft.com/en-us/azure/devops/organizations/billing/buy-more-build-vs?view=azure-devops を参照

ただし、[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)での設定例・実行例の多くは.NetアプリだったりWebアプリで、Windows + Visual Studio C++で開発するアプリケーションでのCI/CDに関しては、日本語の情報どころか、英語の情報も少ない。それどころかユーザーが少ないからか、今回セットアップが成功するまでWorkaroundが必要な問題点がいくつもあった。

# [Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)を使う

## [Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)とは

(2019年7月現在)

[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)とは、[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/)の中の1サービスである。
[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/)はMicrosoftの開発プラットフォームであり、マイナビの[「Azure DevOps」でチーム開発を行おう](https://news.mynavi.jp/article/zeroazure-25/)によると、以下の5つのサービスをまとめたものになっている。

> * Azure Boards
アジャイル開発やスクラムにおけるタスク管理システムである「カンバン」を提供するサービス。

> * Azure Repos
Gitベースのソースコードバージョン管理のためのサービス。[^4]

> * [Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)
アプリケーションのビルドやデプロイを自動化するCI/CDサービス。

> * Azure Artifacts
自身で作成したライブラリ、パッケージをチームで共有するためのホスティングサービス。

> * Azure Test Plans
探索的テストを実行するためのサービス。探索的テストは事前に作成したテストケースをもとにテストを実施する記述式テストとは異なり、テストを実施しながらシステムの振る舞いに応じて次のテストを考えるテスト。

[^4]: gitのレポジトリホスティングサービスですが、Microsoftは[GitHub](https://github.com)を買って持っています。今後これをどうするつもりなんだろうか？

つまり、提供機能や見た目は[GitLab](https://gitlab.com/)とよく似ている。今回はこの中のPipelinesだけ使うことにする。

## 新規プロジェクト作成

[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/)にも[GitLab](https://gitlab.com/)や[GitHub](https://github.com)のようにOrganization, Projectといった単位があり、自由に作成できる。ここでは、あるアプリケーションのレポジトリのユニットテストをするとする。

まず、空のプロジェクトを作り、Pipelinesを選択すると次のような画面になる。Pipelinesから直接外部の

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/7ad085a6-7fce-b726-e304-b66ef5bfd809.png)

`New pipneline` を選んでWebベースで作っていくことにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/175e3c51-b23a-b89e-32d4-20a7b785a3a5.png)

今回は`Other Git`を選んで、GUIでPipelineの設定をする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/b80b58f0-5134-a9c1-c782-7033eb37fa6d.png)

| 入力 | 説明 |
| --- | --- |
| `Connection name` | gitの接続先のわかりやすい名前 |
| `Git repository URL` | レポジトリのURL(httpsで指定) |
| `User name` | (もし認証が必要なら)https認証のユーザ名 |
| `Password` | (もし認証が必要なら)https認証のパスワード |

注意点としては、ssh接続を指定すると、秘密鍵を指定する方法がないため接続できないので、https接続を指定すること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/7ab6d522-ca20-a82d-349b-b92879c27acc.png)

今回は`Windows classic desktop solution`に相当するので、`.NET Desktop`を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/9147092e-5001-7c0f-f569-576cab74a3d7.png)

すると、なんかそれっぽいパイプラインができている。VSのソリューションファイルがあるならこれで`Save & queue`すればCIできそうな気がする。しかし、VC2019でもVC2017でもそのままでは動かない。

## VC環境の闇(VC2019編)

(2019年7月現在)

早速だが、[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/)のAgent poolに登録されている`Hosted Windows 2019 with VC2019`は腐っている。どうやら、一つのイメージにインストールされているソフトウェアが多すぎてレジストリが壊れているらしい。

https://developercommunity.visualstudio.com/content/problem/539158/hosted-windows-2019-with-vs2019-is-failing-builds.html

によると、PowerShellでレジストリを治せばいいらしい。

```
Set-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots' -Name KitsRoot10 -Value 'C:\Program Files (x86)\Windows Kits\10\'
```

このためには次のように`PowerShell Script`タスクを足して、`Inline`を選択して、上のコマンドレットを実行すればよい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/a609ad8f-c86e-c2bd-e251-595ffe094930.png)

## Google Test Integrationの闇(VS2017編)

(2019年7月現在)

VC2017では、Google Test Integrationを自動では見つけてくれないというバグがある。

https://developercommunity.visualstudio.com/content/problem/215878/vstestconsoleexe-fails-to-run-the-gtest-unit-tests.html

そのため、`TestAdapterPath`の`Path to custom test adapters`に以下の設定が必要である。

```
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\drknwe51.xnq
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/342e540d-4f7c-3c4b-b077-11e2bdee345d.png)

## 実行結果の表示

(2019年7月現在)

そんなこんなで準備を終えると、右上の`Save & queue`または`Queue`を押すとPipelineを実行することができる。ビルドとテストが成功すると、以下のようなテスト結果が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/4d9a90a5-effa-c662-5a9d-127c85730fb0.png)

少しでもテスト結果が表示できれば、あとはどんどんテストを増やすのみ。どんどん書いていこう！

## (参考)テスト設定のダウンロード

テストの設定はダウンロードできます。`Builds`の`Queue`ボタンの右側のメニューから`Export`を選ぶと、json形式のファイルをダウンロードできます。手元で編集したjsonを使いたい場合は`New`から`Import a pipeline`を選ぶとjsonファイルをアップロードできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9252/6b48d519-0a7e-895c-d273-a8a7cd18911b.png)

# まとめ

Visual StudioでのC++ソフトウェアの開発は、Intellisenseの存在など、開発環境としては素晴らしいのだが、CIサービスとしての利用が進んではいないのか、設定にはLinuxにはない闇が多くて、なかなか大変である。しかし、CIできるということは、開発者本人以外のビルド環境を構築できるということなので、開発を属人化させないためにも大切である。みんなどんどんテストを回そう！