Distribuire file insieme ai test MSTest

Alcuni test richiedono file aggiuntivi in fase di esecuzione, ad esempio dati di test, file di configurazione, master golden o dipendenze native. Utilizzare DeploymentItemAttribute per dichiarare file e cartelle che devono essere disponibili accanto all'assembly di test all'esecuzione di ogni test.

Informazioni generali

Quando si applica [DeploymentItem] a una classe di test o a un metodo di test, MSTest copia i file o le cartelle specificati nella directory esposta da TestContext.DeploymentDirectory prima dell'esecuzione di qualsiasi test nell'ambito. La directory di distribuzione è anche la directory di lavoro corrente per il test, quindi il codice di test può aprire i file usando i nomi con cui sono stati copiati.

L'attributo accetta un percorso relativo o assoluto:

  • I percorsi relativi sono risolti rispetto alla directory di output della compilazione (la cartella che contiene l'assembly di test, ad esempio bin\Debug\net10.0\).
  • I percorsi assoluti vengono usati as-is.

Importante

In MSTest 3.x gli elementi di distribuzione vengono copiati per ogni esecuzione di test. Per rendere disponibile un file in fase di distribuzione, il file deve esistere già nella directory di output di compilazione (o copiarlo).

Applicare [DeploymentItem]

L'attributo può essere applicato a un metodo di test, a una classe di test o a entrambi. Sono consentite più istanze e possono essere combinate:

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 si applica [DeploymentItem] a una classe di test, la classe deve contenere almeno un metodo di test. Applicarlo a una classe che dispone solo di metodi AssemblyInitialize o ClassInitialize non ha alcun effetto. L'analizzatore MSTEST0035 segnala questo uso improprio.

Sovraccarichi del costruttore

DeploymentItemAttribute ha due costruttori: DeploymentItemAttribute(string path) e DeploymentItemAttribute(string path, string outputDirectory).

DeploymentItemAttribute(string path)

Copia il file o la cartella identificata da path nella radice della directory di distribuzione.

// 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 gli elementi in una sottodirectory della directory di distribuzione, specificata da 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")]

L'argomento outputDirectory deve essere un percorso di cartella. Non può essere usato per rinominare il file. Per distribuire un file con un nome diverso, rinominarlo nella cartella di origine (o usare un passaggio di post-compilazione).

Verificare che i file di origine raggiungano la directory di output di compilazione

Poiché i percorsi relativi vengono risolti nella directory di output di compilazione, il file o la cartella di origine devono essere già presenti. Esistono due modi comuni per ottenere questo risultato.

Usare <None> o <Content> con CopyToOutputDirectory

Aggiungere i file al progetto di test e contrassegnarli per copiarli nella directory di output di compilazione:

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

Dopo una compilazione, la TestFiles cartella viene replicata in bin\<Configuration>\<TargetFramework>\TestFiles\e [DeploymentItem("TestFiles")] viene risolta correttamente.

Usare una destinazione post-compilazione

Per i file che risiedono all'esterno del progetto di test, copiarli nella directory di output di compilazione come parte della compilazione:

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

Esaminare la directory di distribuzione in fase di esecuzione

Se è necessario il percorso assoluto della directory di distribuzione, ad esempio per passarlo a un processo generato o per registrarlo per la diagnostica, usare 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);
    // ...
}

Per altre informazioni su TestContext, vedere La TestContext classe .

Quando la distribuzione non si verifica

Per impostazione predefinita, MSTest crea una directory di distribuzione per ogni esecuzione e vi copia gli elementi. È possibile disabilitare la distribuzione in un .runsettings file in modo che i test vengano eseguiti direttamente dalla directory di output di compilazione:

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

Quando la distribuzione è disabilitata, [DeploymentItem] gli attributi non hanno alcun effetto e il test viene eseguito nella directory di output di compilazione stessa. Per altre opzioni di configurazione, vedere Configurare MSTest.

Modalità legacy e .testsettings

Quando MSTest viene eseguito in modalità legacy (viene usato un .testsettings file o RunSettings/MSTest/ForcedLegacyMode è impostato su true in un .runsettings file), i percorsi relativi potrebbero essere risolti nella directory radice della soluzione anziché nella directory di output della compilazione. Evita la modalità legacy per i nuovi progetti: la configurazione moderna basata su .runsettings è l'approccio consigliato.

Procedure consigliate

  • Preferisci CopyToOutputDirectory ai percorsi relativi annidati. Non accedere alle cartelle sorgente con percorsi in stile ..\..\: vincolano i test a una specifica struttura del repository. Inserire per prima cosa i file nella directory di output della build.
  • Mantenere gli elementi di distribuzione di piccole dimensioni. Ogni elemento viene copiato per ogni esecuzione di test; i file di grandi dimensioni rallentano l'esecuzione dei test.
  • Usare le cartelle per distribuire insieme gli asset correlati. [DeploymentItem("TestFiles")] è più facile da gestire rispetto a decine di attributi per file.
  • Preferisce le risorse incorporate o i dati in memoria per le piccole fixture. Le risorse incorporate eliminano la necessità di distribuzione ed evitano operazioni di I/O in fase di test.
  • Non fare affidamento sul fatto che la directory di lavoro coincida con la directory del progetto. Durante l'esecuzione del test, la directory di lavoro è la directory di distribuzione, non la cartella del progetto di test.

Vedere anche