將檔案部署與 MSTest 測試同時進行

有些測試在執行時需要額外的檔案,例如測試資料、設定檔、黃金檔案或原生依賴項目。 使用 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] 測試類別時,該類別必須包含至少一個測試方法。 套用到只有 AssemblyInitializeClassInitialize 方法的類別上是沒有效果的。 分析儀 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")] 比管理數十個檔案各自的屬性更容易維護。
  • 對於小型測試資料,建議優先使用內嵌資源或記憶體中的資料。 嵌入式資源消除了部署需求,並避免測試時的輸入輸出。
  • 不要只指望工作目錄就是專案目錄。 在測試執行時,工作目錄是部署目錄,而非測試專案資料夾。

另請參閱