Usar a estrutura de MSTest em testes de unidades

O framework MSTest oferece suporte a teste de unidade no Visual Studio. Use as classes e os membros do namespace Microsoft.VisualStudio.TestTools.UnitTesting quando você estiver codificando testes de unidade. Você também pode usá-los quando estiver refinando um teste de unidade que foi gerado a partir do código.

Membros da estrutura

Para ajudar a fornecer uma visão geral mais clara da estrutura de teste de Unidade, esta seção organiza os membros do namespace Microsoft.VisualStudio.TestTools.UnitTesting em grupos de funcionalidades relacionadas.

Observação

Os elementos de atributo, cujos nomes terminam com "Attribute", podem ser usados com ou sem "Attribute" no final e para construtores sem parâmetros com ou sem parênteses. Por exemplo, os exemplos de código a seguir funcionam de forma idêntica:

[TestClass()]

[TestClassAttribute()]

[TestClass]

[TestClassAttribute]

Atributos usados para identificar classes de teste e métodos

Cada classe de teste deve ter o atributo TestClass e cada método de teste deve ter o atributo TestMethod. Para obter mais informações, confira Anatomia de um teste de unidade.

TestClassAttribute

O atributo TestClass marca uma classe que contém testes e, opcionalmente, métodos de inicialização ou limpeza.

Esse atributo pode ser estendido para atualizar ou estender o comportamento.

Exemplo:

[TestClass]
public class MyTestClass
{    
}

Testmethodattribute

O atributo TestMethod é usado dentro de um TestClass para definir o método de teste real a ser executado.

O método deve ser um método de instância definido como public void ou public Task (opcionalmente async) e ser sem parâmetros.

Exemplo

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public void TestMethod()
    {
    }
}
[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async Task TestMethod()
    {
    }
}

Atributos usados para teste controlado por dados

Use os seguintes elementos para configurar testes de unidade controlados por dados. Para obter mais informações, confira Criar um teste de unidade controlado por dados e Usar um arquivo de configuração para definir uma fonte de dados.

DataRow

O DataRowAttribute permite que você forneça dados embutidos usados ao invocar o método de teste. Ele pode aparecer uma ou várias vezes em um método de teste. Ele deve ser combinado com TestMethodAttribute ou DataTestMethodAttribute.

O número e os tipos de argumentos devem corresponder exatamente à assinatura do método de teste.

Exemplos de chamadas válidas:

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, "message", true, 2.0)]
    public void TestMethod1(int i, string s, bool b, float f) {}
    
    [TestMethod]
    [DataRow(new string[] { "line1", "line2" })]
    public void TestMethod2(string[] lines) {}

    [TestMethod]
    [DataRow(null)]
    public void TestMethod3(object o) {}

    [TestMethod]
    [DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
    public void TestMethod4(string[] input, string[] expectedOutput) {}
}

Observe que você também pode usar o params recurso para capturar várias entradas do DataRow.

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, 3, 4)]
    public void TestMethod(params int[] values) {}
}

Exemplos de combinações inválidas:

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2)] // Not valid, we are passing 2 inline data but signature expects 1
    public void TestMethod1(int i) {}

    [TestMethod]
    [DataRow(1)] // Not valid, we are passing 1 inline data but signature expects 2
    public void TestMethod2(int i, int j) {}

    [TestMethod]
    [DataRow(1)] // Not valid, count matches but types do not match
    public void TestMethod3(string s) {}
}

Observação

A partir do MSTest v3, quando você deseja passar exatamente duas matrizes, não é mais necessário encapsular a segunda matriz em uma matriz de objetos. Antes: [DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })] A partir da v3: [DataRow(new string[] { "a" }, new string[] { "b" })]

Você pode modificar o nome de exibição usado no Visual Studio e os agentes para cada instância do DataRowAttribute definindo a propriedade DisplayName.

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, DisplayName= "Functional Case FC100.1")]
    public void TestMethod(int i, int j) {}
}

Você também pode criar seu próprio atributo de linha de dados especializado herdando o DataRowAttribute.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomDataRowAttribute : DataRowAttribute
{
}

[TestClass]
public class TestClass
{
    [TestMethod]
    [MyCustomDataRow(1)]
    public void TestMethod(int i) {}
}

Atributos usados para fornecer inicialização e limpezas

Um método decorado com um dos seguintes atributos é chamado no momento em especificado por você. Para obter mais informações, confira Anatomia de um teste de unidade.

Assembly

AssemblyInitialize é chamado logo após seu assembly ser carregado e AssemblyCleanup é chamado logo antes de seu assembly ser descarregado.

Os métodos marcados com esses atributos devem ser definidos como static void ou static Task, em um TestClass e aparecem apenas uma vez. A parte de inicialização requer um argumento do tipo TestContext e o argumento cleanup no.

[TestClass]
public class MyTestClass
{
    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static void AssemblyCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [AssemblyInitialize]
    public static async Task AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static async Task AssemblyCleanup()
    {
    }
}

Classe

ClassInitialize é chamado logo antes de sua classe ser carregada (mas após o construtor estático) e ClassCleanup é chamado logo após a sua classe ser descarregada.

É possível controlar o comportamento da herança: somente para a classe atual usando InheritanceBehavior.None ou para todas as classes derivadas usando InheritanceBehavior.BeforeEachDerivedClass.

Também é possível configurar se a limpeza de classe deve ser executada no final da classe ou no final do assembly (não há mais suporte desde o MSTest v4, pois EndOfClass é o comportamento padrão, e o único comportamento, de limpeza de classe).

Os métodos marcados com esses atributos devem ser definidos como static void ou static Task, em um TestClass e aparecem apenas uma vez. A parte de inicialização requer um argumento do tipo TestContext e o argumento cleanup no.

[TestClass]
public class MyTestClass
{
    [ClassInitialize]
    public static void ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [ClassInitialize]
    public static async Task ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static async Task ClassCleanup()
    {
    }
}

Teste

TestInitialize é chamado logo antes do teste ser iniciado e TestCleanup é chamado logo após a conclusão do teste.

O TestInitialize é semelhante ao construtor de classe, mas geralmente é mais adequado para inicializações longas ou assíncronas. O TestInitialize é sempre chamado após o construtor e chamado para cada teste (incluindo cada linha de dados de testes controlados por dados).

O TestCleanup é semelhante à classe Dispose (ou DisposeAsync), mas geralmente é mais adequado para limpezas longas ou assíncronas. O TestCleanup é sempre chamado pouco antes do DisposeAsync/Dispose e chamado para cada teste (incluindo cada linha de dados de testes controlados por dados).

Os métodos marcados com esses atributos devem ser definidos como void ou Task, em um TestClass, ser sem parâmetros e aparecer uma ou várias vezes.

[TestClass]
public class MyTestClass
{
    [TestInitialize]
    public void TestInitialize()
    {
    }

    [TestCleanup]
    public void TestCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [TestInitialize]
    public async Task TestInitialize()
    {
    }

    [TestCleanup]
    public async Task TestCleanup()
    {
    }
}

Testes de unidade podem verificar comportamentos específicos do aplicativo pelo uso de vários tipos de asserções, exceções e atributos. Para obter mais informações, confira Usando as classes Assert.

A classe TestContext

Os seguintes atributos e os valores atribuídos a eles aparecem na janela Propriedades do Visual Studio de um método de teste específico. Esses atributos não devem ser acessados por meio do código do teste de unidade. Em vez disso, eles afetam as maneiras pelas quais o teste de unidade é utilizado ou executado, seja por meio do IDE do Visual Studio ou pelo mecanismo de testes do Visual Studio. Por exemplo, alguns desses atributos aparecem como colunas nas janelas Gerenciador de Testes e Resultados do Teste, o que significa que é possível usá-las para agrupar e classificar testes e resultados de teste. Um desses atributos é TestPropertyAttribute, que pode ser usado para adicionar metadados arbitrários a testes de unidade. Por exemplo, é possível usá-lo para armazenar o nome de uma passagem de teste coberta pelo teste em questão, por meio da marcação do teste de unidade com [TestProperty("TestPass", "Accessibility")]. Como alternativa, você pode usá-lo para armazenar um indicador de que o tipo de teste é com o [TestProperty("TestKind", "Localization")]. A propriedade criada por você com esse atributo e o valor da propriedade atribuído são exibidos na janela Propriedades do Visual Studio sob o título Especificidades do teste.

DeploymentItemAttribute

A estrutura MSTest V2 introduziu DeploymentItemAttribute para copiar arquivos ou pastas especificadas como itens de implantação para o diretório de implantação (sem adicionar um caminho de saída personalizado, os arquivos copiados estarão na pasta TestResults dentro da pasta do projeto). O diretório de implantação é onde todos os itens de implantação estão presentes junto com a DLL do projeto de teste.

Ele pode ser usado em classes de teste (classes marcadas com o atributo TestClass) ou em métodos de teste (métodos marcados com o atributo TestMethod).

Os usuários podem ter várias instâncias do atributo para especificar mais de um item.

E aqui você pode ver seus construtores.

Exemplo

[TestClass] 
[DeploymentItem(@"C:\classLevelDepItem.xml")]   // Copy file using some absolute path
public class UnitTest1
{
    [TestMethod]
    [DeploymentItem(@"..\..\methodLevelDepItem1.xml")]   // Copy file using a relative path from the dll output location
    [DeploymentItem(@"C:\DataFiles\methodLevelDepItem2.xml", "SampleDataFiles")]   // File will be added under a SampleDataFiles in the deployment directory
    public void TestMethod1()
    {
        string textFromFile = File.ReadAllText("classLevelDepItem.xml");
    }
}

Classes de configuração de teste

Atributos usados para gerar relatórios

Os atributos desta seção relacionam o método de teste decorados por eles a entidades na hierarquia do projeto de um projeto de equipe Team Foundation Server.

Classes usadas com acessadores particulares

Você pode gerar um teste de unidade para um método privado. Essa geração cria uma classe de acessador particular, que instancia um objeto da classe PrivateObject. A classe PrivateObject é uma classe wrapper que usa reflexão como parte do processo do acessador particular. A classe PrivateType é semelhante, mas é usada para chamar métodos estáticos privados em vez de chamar os métodos de instância privada.

Confira também