公式はこちらのようです。
Windows & Visual Studio があれば
dotnet test --collect "Code Coverage"
クロスプラとフォーム環境では
dotnet test --collect:"XPlat Code Coverage"
■ dotnet test --collect "Code Coverage"
ということでとりあえず、実行してみます。
> dotnet test --collect "Code Coverage" ClassLibrary1 成功しました (0.4 秒) → ClassLibrary1\bin\Debug\net10.0\ClassLibrary1.dll DTestProject1 成功しました (0.4 秒) → CTestProject1\bin\Debug\net10.0\DTestProject1.dll DTestProject2 成功しました (0.5 秒) → CTestProject2\bin\Debug\net10.0\DTestProject2.dll XXXXXXXXXX\ClassLibrary1\CTestProject1\bin\Debug\net10.0\DTestProject1.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 XXXXXXXXXX\ClassLibrary1\CTestProject2\bin\Debug\net10.0\DTestProject2.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 DTestProject1 テスト 成功しました (4.5 秒) DTestProject2 テスト 成功しました (4.4 秒) テスト概要: 合計: 2, 失敗数: 0, 成功数: 2, スキップ済み数: 0, 期間: 4.5 秒 7.6 秒後に 成功しました をビルド 添付ファイル: XXXXXXXXXX\ClassLibrary1\CTestProject2\TestResults\d240d911-a252-441a-8539-9c52dbca380c\XXXXXXXXXXXXX.coverage
実行できました。結果として .coverage ファイルが生まれています。このファイル、Visual Studio Code で開こうとすると

無念です。
Visual Studio で開くとこんな感じ。

ちょっと扱いづらいですね。
■ dotnet test --collect:"XPlat Code Coverage"
やってみましょう。
> dotnet test --collect:"XPlat Code Coverage" 復元が完了しました (4.5 秒) プレビュー版の .NET を使用しています。https://aka.ms/dotnet-support-policy をご覧ください ClassLibrary1 成功しました (0.5 秒) → ClassLibrary1\bin\Debug\net10.0\ClassLibrary1.dll DTestProject1 成功しました (1.3 秒) → CTestProject1\bin\Debug\net10.0\DTestProject1.dll XXXXXXXXXX\ClassLibrary1\CTestProject1\bin\Debug\net10.0\DTestProject1.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 DTestProject1 テスト 2 件の警告付きで成功しました (3.3 秒) C:\Program Files\dotnet\sdk\10.0.100-preview.1.25120.13\Microsoft.TestPlatform.targets(48,5): warning : データ コレクション : フレンドリ名が 'XPlat Code Coverage' の datacollector が見つかりません。 C:\Program Files\dotnet\sdk\10.0.100-preview.1.25120.13\Microsoft.TestPlatform.targets(48,5): warning : データ コレクション : データ コレクター 'XPlat Code Coverage' が見つかりませんでした DTestProject2 成功しました (6.8 秒) → CTestProject2\bin\Debug\net10.0\DTestProject2.dll XXXXXXXXXX\ClassLibrary1\CTestProject2\bin\Debug\net10.0\DTestProject2.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 DTestProject2 テスト 2 件の警告付きで成功しました (3.2 秒) C:\Program Files\dotnet\sdk\10.0.100-preview.1.25120.13\Microsoft.TestPlatform.targets(48,5): warning : データ コレクション : フレンドリ名が 'XPlat Code Coverage' の datacollector が見つかりません。 C:\Program Files\dotnet\sdk\10.0.100-preview.1.25120.13\Microsoft.TestPlatform.targets(48,5): warning : データ コレクション : データ コレクター 'XPlat Code Coverage' が見つかりませんでした テスト概要: 合計: 2, 失敗数: 0, 成功数: 2, スキップ済み数: 0, 期間: 8.5 秒 16.1 秒後に 4 件の警告付きで成功しました をビルド
動きませんでした。
■ 環境を整えてもう一回
coverlet インストール。
dotnet add CTestProject1 package coverlet.collector
もう一回
> dotnet test --collect:"XPlat Code Coverage" 復元が完了しました (1.9 秒) プレビュー版の .NET を使用しています。https://aka.ms/dotnet-support-policy をご覧ください ClassLibrary1 成功しました (0.5 秒) → ClassLibrary1\bin\Debug\net10.0\ClassLibrary1.dll DTestProject2 成功しました (5.4 秒) → CTestProject2\bin\Debug\net10.0\DTestProject2.dll DTestProject1 成功しました (5.7 秒) → CTestProject1\bin\Debug\net10.0\DTestProject1.dll XXXXXXXXXX\ClassLibrary1\CTestProject1\bin\Debug\net10.0\DTestProject1.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 XXXXXXXXXX\ClassLibrary1\CTestProject2\bin\Debug\net10.0\DTestProject2.dll でテスト並列処理が有効にされています (Workers: 8、Scope: MethodLevel)。 DTestProject1 テスト 成功しました (5.9 秒) DTestProject2 テスト 成功しました (6.1 秒) テスト概要: 合計: 2, 失敗数: 0, 成功数: 2, スキップ済み数: 0, 期間: 6.0 秒 15.2 秒後に 成功しました をビルド 添付ファイル: XXXXXXXXXX\ClassLibrary1\CTestProject2\TestResults\ec10a73e-369a-4d01-83f7-d0560e65bd45\coverage.cobertura.xml XXXXXXXXXX\ClassLibrary1\CTestProject1\TestResults\ce718119-2fd4-446c-8d6b-28898392aa3c\coverage.cobertura.xml
できました。
GUID部分は毎回変わって制御・予測は不能なようなのでここはもう何も信じないでもしツールを作るなら挑まないといけない感じですね。
ファイルのフォーマットを指定する
ファイルはフォーマットをすることができ、複数指定することもできます。
dotnet test --collect:"XPlat Code Coverage;Format=json,lcov,cobertura"
ファイルが複数生まれました。
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2025/04/20 XX:XX 2506 coverage.cobertura.xml -a---- 2025/04/20 XX:XX 817 coverage.info -a---- 2025/04/20 XX:XX 1032 coverage.json
ファイルの中身
情報は、ちょっと差があるようで、一番情報が想像しやすそうな情報が書かれているのが xml ファイルでした。 json は処理分岐の位置なども詳細に出ているようですが、それより xml が分岐のカバー率だけ出ている? など。
<?xml version="1.0" encoding="utf-8"?> <coverage line-rate="0.2" branch-rate="1" version="1.9" timestamp="1745119100" lines-covered="1" lines-valid="5" branches-covered="0" branches-valid="0"> <sources> <source>X:\</source> </sources> <packages> <package name="ClassLibrary1" line-rate="1" branch-rate="1" complexity="1"> <classes> <class name="ClassLibrary1.Class1" filename="XXXXXXXXXX\ClassLibrary1\ClassLibrary1\Class1.cs" line-rate="1" branch-rate="1" complexity="1"> <methods> <method name="Method" signature="(System.Int32)" line-rate="1" branch-rate="1" complexity="1"> <lines> <line number="5" hits="1" branch="False" /> </lines> </method> </methods> <lines> <line number="5" hits="1" branch="False" /> </lines> </class> </classes> </package> <package name="TestProject2" line-rate="0" branch-rate="1" complexity="2"> <classes> <class name="AutoGeneratedProgram" filename="XXXXXXXXXX\.nuget\packages\microsoft.net.test.sdk\17.12.0\build\netcoreapp3.1\Microsoft.NET.Test.Sdk.Program.cs" line-rate="0" branch-rate="1" complexity="1"> <methods> <method name="Main" signature="(System.String[])" line-rate="0" branch-rate="1" complexity="1"> <lines> <line number="4" hits="0" branch="False" /> </lines> </method> </methods> <lines> <line number="4" hits="0" branch="False" /> </lines> </class> <class name="TestProject2.Test1" filename="XXXXXXXXXX\ClassLibrary1\CTestProject2\Test1.cs" line-rate="0" branch-rate="1" complexity="1"> <methods> <method name="TestMethod1" signature="()" line-rate="0" branch-rate="1" complexity="1"> <lines> <line number="8" hits="0" branch="False" /> <line number="9" hits="0" branch="False" /> <line number="10" hits="0" branch="False" /> </lines> </method> </methods> <lines> <line number="8" hits="0" branch="False" /> <line number="9" hits="0" branch="False" /> <line number="10" hits="0" branch="False" /> </lines> </class> </classes> </package> </packages> </coverage>
とりあえず、<line number="8" hits="0" branch="False" /> の hits が 0 のものとそうでないものを数えてみるとどのくらいテストが書けているか目安にできそうですね。