tl;dr
C#のテストプロジェクトは分けましょう。当たり前かもしれませんが。
発端
Azure Functionsを使ったC#プロジェクトを書き始めて、軽い動作確認でユニットテストっぽく書きたいと思い、xunitを入れて実行したら90秒待たされた後に以下のエラー。
$ dotnet test
Testhost プロセスが次のエラーにより終了しました: A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Users\2011050\Desktop\testcs\bin\Debug\netcoreapp2.1\bin\'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the C:\Users\2011050\Desktop\testcs\bin\Debug\netcoreapp2.1\bin\testhost.runtimeconfig.json file specifying the appropriate framework.
原因が全くわからない。
該当のプロジェクトファイルはこんな感じ。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
</Project>
ライブラリを追加したり削除したりSDK変えたりしていたところ、以下のことが分かった。
-
Microsoft.NET.Sdk.Functions
がいるとダメで、バージョンは1.0.23
~1.0.29
の間は全部ダメ(それ以前はnetcoreapp2.1をサポートしてないっぽい?) - dotnet sdkも2.1.700と2.2.103を試した
- TFMはnetcoreapp2.1,netcoreapp2.2を試した)
なぜMicrosoft.NET.Sdk.Functions
とMicrosoft.NET.Test.Sdk
が相乗りした時だけタイムアウトしてしまうのかはよくわからない。
が、そもそもテストなんだからプロダクトのコードとテストコードを同じプロジェクトにするのは良くないのでは、と気づく。Microsoft.NET.Sdk.Functions
に依存しないプロジェクトを起こしてそこからテストすればよい。
というわけで、src,testの2つのプロジェクトに分けた。大本の原因はわからなかったけども。
とりあえずdotnetコマンドでもVSCode上からのメソッド単位実行もできるようになり満足。
無駄知識
色々調べている過程で無駄知識を得た。
TFM=Target Framework Moniker
https://docs.microsoft.com/ja-jp/dotnet/standard/frameworks に書いてあった
IsTestProjectプロパティ
.Net Core SDK 2.1.500以降からは、<PackageReference Include="Microsoft.NET.Test.Sdk" Version="xxxx" />
があると、テストプロジェクトとして認識する。どういう仕組みかわからないが、このIsTestProjectプロパティをつけるらしい。逆にないと認識しなくなる。
しかしIsTestProjectプロパティ自体はあまり情報がない。いつどこで入ったんだろう。
https://github.com/search?l=&q=IsTestProject+user%3Adotnet+user%3Amicrosoft&type=Code
dotnet test -v diag
パフォーマンス分析用のログがめちゃくちゃ出る。今回は役に立たなかった。
VSTEST_CONNECTION_TIMEOUT
環境変数
冒頭で90秒ぐらいでエラーになる所。90秒は長すぎるというときにこの環境変数が使えるかもしれない。
SDK 2.0.3だと動かなかったので、2.1以上じゃないと機能しないかもしれない。今回は役に経たなかった
VSTEST_CONNECTION_TIMEOUT=5 dotnet test