有些測試在執行時需要額外的檔案,例如測試資料、設定檔、黃金檔案或原生依賴項目。 使用 DeploymentItemAttribute 宣告在每次測試執行時應可於測試組件旁取得的檔案和資料夾。
概觀
當您將 [DeploymentItem] 套用至測試類別或測試方法時,MSTest 會在該範圍內的任何測試執行之前,將指定的檔案或資料夾複製到 TestContext.DeploymentDirectory 所公開的目錄中。 部署目錄同時也是測試目前的工作目錄,所以你的測試程式碼可以用複製的名稱開啟檔案。
屬性接受相對路徑或絕對路徑:
-
相對路徑 會根據建置輸出目錄(例如
bin\Debug\net10.0\包含測試組件的資料夾)解析。 - 絕對路徑會按原樣使用。
Important
在 MSTest 3.x 中,部署項目會在每次測試執行中複製。 若要在部署時提供檔案,該檔案必須已存在於建置輸出目錄中(或已被複製至)。
套用 [DeploymentItem]
此屬性可套用於測試方法、測試類別,或兩者兼具。 允許多個實例並結合:
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
[DeploymentItem(@"TestFiles\shared-config.json")]
public class ConfigurationTests
{
[TestMethod]
[DeploymentItem(@"TestFiles\customers.csv")]
public void LoadCustomers_FromCsv_ReturnsAllRows()
{
// Both shared-config.json (from the class) and customers.csv (from
// the method) are available in the deployment directory.
Assert.IsTrue(File.Exists("shared-config.json"));
Assert.IsTrue(File.Exists("customers.csv"));
}
}
Note
當你申請 [DeploymentItem] 測試類別時,該類別必須包含至少一個測試方法。 套用到只有 AssemblyInitialize 或 ClassInitialize 方法的類別上是沒有效果的。 分析儀 MSTEST0035 會標記此類濫用。
建構器過載
DeploymentItemAttribute 有兩個構造子: DeploymentItemAttribute(string path) 和 DeploymentItemAttribute(string path, string outputDirectory)。
DeploymentItemAttribute(string path)
將所識別 path 的檔案或資料夾複製到部署目錄的根目錄中。
// Copy a single file from the build output directory.
[DeploymentItem("settings.json")]
// Copy a file that lives in a subfolder of the build output directory.
// The file is copied to the root of the deployment directory (the
// "Resources" folder is not preserved).
[DeploymentItem(@"Resources\test-data.xml")]
// Copy the entire TestFiles folder (and all of its subfolders) into the
// deployment directory.
[DeploymentItem("TestFiles")]
DeploymentItemAttribute(string path, string outputDirectory)
將這些項目複製到部署目錄中由 outputDirectory 指定的子目錄。
// Creates a "Data" subfolder under the deployment directory, then copies
// test-data.xml into it. The file is reached at "Data\test-data.xml".
[DeploymentItem("test-data.xml", "Data")]
// Copies the contents of the Resources folder into a "Resources"
// subfolder of the deployment directory.
[DeploymentItem("Resources", "Resources")]
參數 outputDirectory 必須是資料夾路徑。 它不能用來重新命名檔案。 若要部署名稱不同的檔案,請在來源資料夾中重新命名(或使用建置後步驟)。
確保原始碼檔案能到達建置輸出目錄
由於相對路徑是根據建置輸出目錄解析的,來源檔案或資料夾必須已經存在。 有兩種常見的方法可以達成這個目標。
將 <None> 或 <Content> 與 CopyToOutputDirectory 搭配使用
將檔案加入你的測試專案,並標記要複製到 build 輸出目錄:
<ItemGroup>
<None Update="TestFiles\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
建置完成後,TestFiles 資料夾會複製到 bin\<Configuration>\<TargetFramework>\TestFiles\,且 [DeploymentItem("TestFiles")] 也能正確解析。
使用建置後目標
對於不在測試專案中的檔案,將它們複製到建置輸出目錄,作為建置的一部分:
<Target Name="CopySharedAssets" AfterTargets="Build">
<Copy SourceFiles="@(SharedAsset)"
DestinationFolder="$(OutDir)SharedAssets\" />
</Target>
執行時檢查部署目錄
如果你需要部署目錄的絕對路徑——例如,將它傳遞給你啟動的處理程序,或為了診斷而將其記錄下來——請使用 TestContext.DeploymentDirectory:
using System.IO;
[TestMethod]
[DeploymentItem(@"TestFiles\input.json")]
public void ProcessInput_FromDeployedFile_Succeeds()
{
string fullPath = Path.Combine(TestContext.DeploymentDirectory, "input.json");
string contents = File.ReadAllText(fullPath);
// ...
}
如需更多關於 TestContext 的資訊,請參閱 TestContext 類別。
當未進行部署時
預設情況下,MSTest 會建立一個每次執行的部署目錄,並將項目複製到其中。 你可以在檔案 .runsettings 中關閉部署,讓測試直接從建置輸出目錄執行:
<RunSettings>
<MSTest>
<DeploymentEnabled>False</DeploymentEnabled>
</MSTest>
</RunSettings>
當部署被停用時, [DeploymentItem] 屬性不會有影響,測試會在建置輸出目錄本身執行。 欲了解更多設定選項,請參閱 配置 MSTest。
舊版模式和 .testsettings
當 MSTest 以舊版模式執行時(使用 .testsettings 檔案,或在 .runsettings 檔案中將 RunSettings/MSTest/ForcedLegacyMode 設為 true),相對路徑可能會相對於解決方案根目錄而非建置輸出目錄進行解析。 新專案避免使用舊有模式——建議採用現代 .runsettings基礎的配置。
最佳做法
- 優先使用
CopyToOutputDirectory,而非深層相對路徑。 不要進入帶有..\..\樣式路徑的原始碼資料夾——它們會把你的測試綁定在特定的資料庫配置上。 先把檔案放在建置輸出目錄裡。 - 讓部署項目保持精簡。 每個項目都會在每次測試中複製;大型檔案會減緩測試執行。
- 用資料夾來一起部署相關資產。
[DeploymentItem("TestFiles")]比管理數十個檔案各自的屬性更容易維護。 - 對於小型測試資料,建議優先使用內嵌資源或記憶體中的資料。 嵌入式資源消除了部署需求,並避免測試時的輸入輸出。
- 不要只指望工作目錄就是專案目錄。 在測試執行時,工作目錄是部署目錄,而非測試專案資料夾。