
platform-detection
熱門識別 .NET 專案的測試平台、測試框架、命令模式,以及 SDK 風格與傳統專案系統。僅用於「使用哪個測試平台/框架?」、「VSTest 或 MTP?」或「此專案使用哪個執行器?」,包括橋接設定、UseVSTest 退出選項,以及不相容或衝突的 VSTest/MTP 設定。解析 global.json、專案檔、packages.config、Directory.Build.props 和 Directory.Packages.props 的優先順序,以判斷 MSTest/xUnit/NUnit/TUnit。若需執行/篩選測試、確切命令或旗標、TRX/傾印,以及測試命令/篩選錯誤,請使用 run-tests。請勿用於熱重載或遷移。
識別 .NET 專案的測試平台、測試框架、命令模式,以及 SDK 風格與傳統專案系統。僅用於「使用哪個測試平台/框架?」、「VSTest 或 MTP?」或「此專案使用哪個執行器?」,包括橋接設定、UseVSTest 退出選項,以及不相容或衝突的 VSTest/MTP 設定。解析 global.json、專案檔、packages.config、Directory.Build.props 和 Directory.Packages.props 的優先順序,以判斷 MSTest/xUnit/NUnit/TUnit。若需執行/篩選測試、確切命令或旗標、TRX/傾印,以及測試命令/篩選錯誤,請使用 run-tests。請勿用於熱重載或遷移。
測試平台與框架偵測
判斷專案使用哪個測試平台(VSTest 或 Microsoft.Testing.Platform)以及哪個測試框架(MSTest、xUnit、NUnit、TUnit)。
回應合約
嚴格依照使用者要求的標籤與順序,並以實際分類取代每個佔位符。
先陳述結論:切勿在結論前放置標題、草稿分析、工具語法或重複的範本。
接著用一句簡潔的證據句,說明足以證明每個要求分類的儲存庫事實。
當要求 Framework 時,指出識別該框架的套件或專案 SDK。
僅在發生衝突、設定不完整或目標框架特定差異時,才使用第二句。
Platform 指的是實際執行測試的平台:VSTest 或 MTP。
若衝突或不完整的設定導致無法執行,請回報為 unavailable,而非虛構成功的平台。
在草擬證據前套用此範圍閘門:
| 使用者要求 | 需包含的證據 | 省略 |
|---|---|---|
| 平台與框架 | 最終執行器選擇器及其勝出來源;識別框架的套件或專案 SDK;必要時,使其可執行的屬性 | 命令模式;常見 SDK 事實;OutputType(除非缺失或衝突) |
| 單一決定性訊號 | 該執行器選擇屬性、其來源為何勝出,以及為何競爭套件不會選擇或暗示 VSTest;仍須指出識別所要求框架的套件或專案 SDK | 橋接、OutputType、SDK 模式,以及設定完整時無關的先決條件 |
| 各目標框架的平台 | 僅依目標而異的條件式最終值 | 常見屬性與專案層級 SDK 評論 |
| 明確退出 | 最終 UseVSTest 值及其勝出來源 |
被取代的預設值(除非造成衝突) |
dotnet test 模式 |
獨立的命令模式與執行平台分類 | 所要求軸線以外的項目 |
若要求的標籤省略 dotnet test mode,請勿在回應中陳述或解釋命令模式。
確切的橋接屬性仍可能是決定性的平台證據,但不要將其轉為 SDK 或 CLI 模式評論。
當匯入優先順序決定屬性時,說明勝出來源為何勝出(例如,較晚匯入或其條件成立),而非僅說明其包含最終值或覆寫其他指派。
將解釋保持在要求的軸線上:
global.json中的 SDK 版本釘選是背景資訊,而非平台選擇器。
僅當其test.runner設定確實選擇 VSTest 或原生 MTP 時,才宣稱global.json選擇了平台。- 若
UseVSTest=true具有決定性,直接說明。請勿推測不存在的test.runner,或將 SDK 釘選描述為額外的平台選擇。 - 若未要求命令模式,請勿加入,即使內部需要它來判斷執行的平台。
當傳統專案要求同時詢問命令系列時,直接加入一行,例如 Command family: MSBuild + vstest.console.exe;請勿將其變成選用替代方案或加入不必要的建置限定詞。
對於檔案支援的要求,先列舉以下設定名稱一次,然後在一次批次作業中讀取所有存在的相關檔案:
global.json、.csproj、packages.config、Directory.Build.props、
Directory.Build.targets、Directory.Packages.props,以及明確匯入的
.props / .targets。專案檔中未出現的設定可能由匯入定義,因此絕不要僅從 .csproj 推斷其最終值。
當儲存庫設定足夠時,請勿搜尋網路或檢查無關檔案。
依實際 MSBuild 匯入順序解析屬性,而非固定的「專案檔勝過 props」規則。
針對每個適用的目標框架:
- 追蹤匯入圖與條件。較晚的適用指派勝出。
Directory.Build.props通常會在專案主體之前匯入,因此無條件的專案指派通常會覆寫它;較晚的.targets可再次覆寫專案。 - 記錄
UseVSTest、框架執行器選擇器、TestingPlatformDotnetTestSupport和OutputType的最終值及其勝出來源。 - 將
Directory.Packages.props視為版本證據,除非它也包含相關屬性。
在套用版本相關預設值之前,先解析套件/SDK 版本。 - 絕不要從套件存在推斷屬性。套件或 SDK 預設值僅在該解析版本確實提供且沒有較晚指派覆寫時才算數。
偵測專案系統
在選擇 CLI 之前先分類專案:
- 根
Sdk屬性或<Sdk>宣告:SDK 風格。 ToolsVersion、Microsoft.Common.props/Microsoft.CSharp.targets匯入、
明確的<Reference>和<Compile Include>項目:傳統非 SDK。packages.config:傳統 NuGet 相依性管理。
傳統專案仍可使用 VSTest 相容配接器,但 dotnet test 並非自動有效的叫用方式。
保留儲存庫指令碼/CI 命令,通常是 MSBuild 後接 vstest.console.exe。
僅當儲存庫設定或文件確立該舊版執行器時,才提及 MSTest.exe。
偵測測試框架
讀取 .csproj、相鄰的 packages.config 和
Directory.Build.props / Directory.Packages.props,尋找:
| 套件或 SDK 參考 | 框架 |
|---|---|
MSTest 中繼套件、<Project Sdk="MSTest.Sdk[/version]"> 或 <Sdk Name="MSTest.Sdk"> |
MSTest |
MSTest.TestFramework + MSTest.TestAdapter |
MSTest(亦適用於 v3/v4) |
xunit、xunit.v3、xunit.v3.mtp-v1、xunit.v3.mtp-v2、xunit.v3.core.mtp-v1、xunit.v3.core.mtp-v2 |
xUnit |
NUnit + NUnit3TestAdapter |
NUnit |
TUnit |
TUnit(僅 MTP) |
在傳統專案中,套件 ID 和版本可能僅出現在 packages.config,而專案包含帶有 HintPath 值的組件 <Reference> 元素。請使用兩者。
偵測執行的測試平台
若使用者明確要求 dotnet test 模式,請在回答前閱讀
references/command-mode.md。
若僅要求平台/框架,請勿載入該參考或提及命令模式。
對於 SDK 8/9 且明確詢問命令模式且無有效橋接的要求,請用一句因果句陳述所有三個事實:執行器使專案具備 MTP 能力,dotnet test 仍處於 VSTest 模式,且缺少橋接表示 VSTest 實際執行測試。
僅當有助於解釋結果時,才提及原生 MTP 命令模式從 SDK 10 開始。
當允許執行且提示或 global.json 未識別 SDK 時,執行 dotnet --version 一次。
對於禁止執行的唯讀識別要求,請勿探查已安裝的 SDK;使用儲存庫事實並陳述任何必要的 SDK 假設。
解析最終屬性值後,依此順序分類:
- 最終
UseVSTest=true選擇 VSTest。若global.json同時選擇原生 MTP 命令模式,回報Platform: unavailable,因為命令模式與專案退出選項衝突。 global.json中的原生 MTP 選擇會以最終OutputType=Exe在 MTP 上執行相容的 MTP 應用程式。僅 VSTest、程式庫輸出或退出選項的專案為 unavailable。- 在 SDK 8/9 上,啟用的 MTP 執行器加上最終
TestingPlatformDotnetTestSupport=true加上最終OutputType=Exe會在 MTP 上執行。 - 若執行器已啟用但橋接不存在或為 false,則雙重能力的 MSTest、NUnit 或 xUnit 專案仍留在 VSTest:執行器建立 MTP 能力,但 SDK 8/9
dotnet test無法觸及它,而 VSTest 配接器會執行測試。若橋接為 true 但未啟用執行器,專案也留在 VSTest。 - 執行器和橋接搭配不可執行的輸出是不完整且 unavailable。僅 MTP 的框架若無法由所選 SDK 路徑觸及,也是 unavailable,而非 VSTest。
保持每個訊號的角色精確:
- 執行器屬性選擇測試應用程式。
TestingPlatformDotnetTestSupport=true讓 SDK 8/9dotnet test觸及該應用程式。OutputType=Exe提供可執行主機形狀。它不選擇或啟用 MTP。
請勿混淆 MSTest 中繼套件與 MSTest.Sdk 專案 SDK。
PackageReference Include="MSTest" 加上 EnableMSTestRunner=true 啟用 MSTest MTP 執行器,但不隱含設定 TestingPlatformDotnetTestSupport。
MSTest.Sdk 預設啟用 MTP 執行器。檢查其解析版本和評估屬性以了解橋接行為:版本 3.8 提供 TestingPlatformDotnetTestSupport,除非較晚指派覆寫它,而 .NET 10 上的較新 SDK 可能預期原生 MTP 模式。
<UseVSTest>true</UseVSTest> 選擇回到 VSTest。
| 訊號 | 意義 |
|---|---|
<Project Sdk="MSTest.Sdk..."> 且無 UseVSTest |
MTP 應用程式;檢查解析的 SDK 版本和評估的橋接屬性 |
MSTest 中繼套件 + <EnableMSTestRunner>true> |
MTP 執行器已啟用;不暗示 VSTest 到 MTP 的橋接 |
<UseMicrosoftTestingPlatformRunner>true |
決定 xUnit 執行器選擇的訊號 |
<EnableMSTestRunner>true> / <EnableNUnitRunner>true> |
決定 MSTest/NUnit 執行器選擇的訊號 |
TestingPlatformDotnetTestSupport=true |
VSTest 到 MTP 橋接的執行先決條件,而非執行器選擇訊號 |
Microsoft.Testing.Platform 套件 |
具備 MTP 能力的應用程式;本身不具決定性 |
TUnit |
僅 MTP 框架 |
最終評估的 <OutputType>Exe</OutputType> |
套件型 MTP 應用程式所需的可執行主機形狀 |
Microsoft.NET.Test.Sdk 單獨不具決定性;它可保留在啟用 MTP 的專案中以供相容性。
當明確覆寫決定結果時,指出最終覆寫及其來源,而非被取代的預設值。
當執行器選擇屬性與 Microsoft.NET.Test.Sdk 競爭時,說明執行器屬性選擇 MTP,而 Microsoft.NET.Test.Sdk 不選擇或暗示 VSTest。它可保留作為相容性支援,但這是次要的。TestingPlatformDotnetTestSupport=true 是橋接先決條件,而非執行器選擇訊號;絕不要說此屬性單獨啟用橋接。
對於詢問哪個單一訊號具有決定性的要求,到此為止。當設定完整時,省略橋接或主機形狀先決條件,僅在需要解釋為何所選執行器無法執行時加入。
使用因果證據,而非訊號集合。例如:
Platform: MTP
Framework: NUnit
Directory.Build.props 提供最終 EnableNUnitRunner=true 和
TestingPlatformDotnetTestSupport=true,因此 NUnit 在 MTP 上執行。
對於不相容的設定,在結論後提供一個最小的對齊選擇,而不修改檔案:
全域選擇專案設定的平台,或移除專案退出選項以使用全域選擇的平台。
條件式與各目標框架屬性
針對每個目標框架評估執行器和橋接屬性。若條件產生不同的執行平台,
明確回報每個目標(例如 net8.0: VSTest、net9.0: MTP),而非將專案收斂為單一全域平台。





