Implantar arquivos junto com testes MSTest

Alguns testes precisam de arquivos extras em runtime, como dados de teste, arquivos de configuração, mestres dourados ou dependências nativas. Use o DeploymentItemAttribute para declarar arquivos e pastas que devem estar disponíveis junto ao assembly de teste quando cada teste for executado.

Visão geral

Quando você aplica [DeploymentItem] a uma classe de teste ou a um método de teste, o MSTest copia os arquivos ou as pastas especificados para o diretório exposto por TestContext.DeploymentDirectory antes da execução de qualquer teste nesse escopo. O diretório de implantação também é o diretório de trabalho atual para o teste, portanto, seu código de teste pode abrir os arquivos por seus nomes copiados.

O atributo aceita um caminho relativo ou absoluto:

  • Caminhos relativos são resolvidos em relação ao diretório de saída da compilação (a pasta que contém a montagem de teste, por exemplo bin\Debug\net10.0\).
  • Caminhos absolutos são usados como estão.

Importante

No MSTest 3.x, os itens de implantação são copiados a cada execução de teste. Para disponibilizar um arquivo no momento da implantação, o arquivo já deve existir (ou ser copiado para) o diretório de saída de build.

Aplicar [DeploymentItem]

O atributo pode ser aplicado a um método de teste, uma classe de teste ou ambos. Várias instâncias são permitidas e podem ser combinadas:

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

Quando você aplica [DeploymentItem] a uma classe de teste, a classe deve conter pelo menos um método de teste. Aplicá-la a uma classe que só tem AssemblyInitialize ou ClassInitialize métodos não tem efeito. O analisador MSTEST0035 sinaliza esse uso indevido.

Sobrecargas do construtor

DeploymentItemAttribute tem dois construtores: DeploymentItemAttribute(string path) e DeploymentItemAttribute(string path, string outputDirectory).

DeploymentItemAttribute(string path)

Copia o arquivo ou a pasta identificados por path para a raiz do diretório de implantação.

// 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)

Copia os itens em um subdiretório do diretório de implantação, fornecido por 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")]

O outputDirectory argumento deve ser um caminho de pasta. Ele não pode ser usado para renomear o arquivo. Para implantar um arquivo com um nome diferente, renomeie-o na pasta de origem (ou use uma etapa pós-build).

Garantir que os arquivos de origem atinjam o diretório de saída de build

Como os caminhos relativos são resolvidos no diretório de saída de build, o arquivo ou pasta de origem já deve estar lá. Há duas maneiras comuns de conseguir isso.

Usar <None> ou <Content> com CopyToOutputDirectory

Adicione os arquivos ao projeto de teste e marque-os para copiar para o diretório de saída de build:

<ItemGroup>
  <None Update="TestFiles\**\*.*">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Após uma compilação, a pasta TestFiles é replicada em bin\<Configuration>\<TargetFramework>\TestFiles\ e [DeploymentItem("TestFiles")] é resolvida corretamente.

Usar um destino para pós-compilação

Para arquivos que ficam fora do projeto de teste, copie-os para o diretório de saída da compilação como parte da compilação:

<Target Name="CopySharedAssets" AfterTargets="Build">
  <Copy SourceFiles="@(SharedAsset)"
        DestinationFolder="$(OutDir)SharedAssets\" />
</Target>

Inspecionar o diretório de implantação em tempo de execução

Se você precisar do caminho absoluto do diretório de implantação , por exemplo, para passá-lo para um processo que você gera ou para registrá-lo para diagnóstico, use 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);
    // ...
}

Para obter mais informações TestContext, consulte a TestContext classe.

Quando a implantação não acontece

Por padrão, o MSTest cria um diretório de implantação por execução e copia itens nele. Você pode desativar a implantação em um arquivo .runsettings para que os testes sejam executados diretamente do diretório de saída da compilação:

<RunSettings>
  <MSTest>
    <DeploymentEnabled>False</DeploymentEnabled>
  </MSTest>
</RunSettings>

Quando a implantação está desativada, os atributos [DeploymentItem] não têm efeito, e o teste é executado no próprio diretório de saída da compilação. Para obter mais opções de configuração, consulte Configurar MSTest.

Modo herdado e .testsettings

Quando o MSTest é executado no modo herdado (um arquivo .testsettings é usado ou RunSettings/MSTest/ForcedLegacyMode é definido como true em um arquivo .runsettings), os caminhos relativos podem ser resolvidos em relação ao diretório raiz da solução em vez do diretório de saída da compilação. Evite o modo legado em novos projetos — a configuração moderna baseada em .runsettings é a abordagem recomendada.

Práticas recomendadas

  • Prefira CopyToOutputDirectory caminhos relativos profundos. Não acesse pastas de código-fonte usando caminhos no estilo ..\..\ — eles prendem seus testes a uma estrutura específica de repositório. Primeiro, coloque os arquivos no diretório de saída da compilação.
  • Mantenha os itens de implantação pequenos. Cada item é copiado para cada execução de teste; arquivos grandes reduzem a execução do teste.
  • Use pastas para implantar ativos relacionados juntos. [DeploymentItem("TestFiles")] é mais fácil de manter do que dezenas de atributos por arquivo.
  • Prefira recursos integrados ou dados na memória para pequenos acessórios. Os recursos incorporados eliminam a necessidade de implantação e evitam operações de entrada/saída durante os testes.
  • Não presuma que o diretório de trabalho seja o diretório do projeto. Durante a execução do teste, o diretório de trabalho é o diretório de implantação, não a pasta do projeto de teste.

Consulte também