DEV Community

Yuri Peixinho
Yuri Peixinho

Posted on

Testes com xUnit

Introdução

No ecossistema do .NET (C#), o xUnité o framework mais utilizado para desenvolver testes de unidade.

O xUnit.net é uma biblioteca de testes que verifica automaticamente se o seu código está funcionando como o esperado. Ele é o sucessor natural de outros frameworks de teste da Microsoft:

  • MSTest → o mais antigo
  • NUnit → o mais popular por um tempo
  • xUnit → o mais moderno, usado em projetos .NET Core e .NET 8+

Como executar o teste?

Em um projeto .NET normalmente teremos o código da aplicação e um outro projeto separado de testes.

MyApp/
 ├── MyApp/              Projeto principal (código da aplicação)
 └── MyApp.Tests/        Projeto de testes (usa xUnit)
Enter fullscreen mode Exit fullscreen mode

Cada método do projeto de teste chama e verifica um método do projeto principal. A ideia é que cada comportamento importante tenha um teste correspondente

Fact e Theory

É importante dominar os conceitos de Fact e Theory para se dar bem com o xUnit.

Fact

É usado para testes que não dependem de parâmetros, ou seja, o comportamento testado é único e direto. Utilize quando quer validar um único cenário.

[Fact]
public void Soma_DeveRetornar5_QuandoSomar2e3()
{
    var calc = new Calculadora();

    var resultado = calc.Somar(2, 3);

    Assert.Equal(5, resultado);
}
Enter fullscreen mode Exit fullscreen mode

Aqui há um único caso: 2 + 3 = 5. Nada muda entre execuções. Se o código passar, ele está certo pra aquele cenário específico.

Theory

É utilizado quando você quer rodar o mesmo teste com diferentes combinações de valores. Você fornece esses valores com [InlineData(...)], e o xUnit executa o mesmo método várias vezes para cada conjunto de dados fornecidos.

É interessante utilizar quando você quer testar o mesmo comportamento para diferentes dados.

[Theory]
[InlineData(2, 3, 5)]
[InlineData(1, 1, 2)]
[InlineData(-2, 2, 0)]
public void Soma_DeveFuncionarParaVariosValores(int a, int b, int esperado)
{
    var calc = new Calculadora();

    var resultado = calc.Somar(a, b);

    Assert.Equal(esperado, resultado);
}
Enter fullscreen mode Exit fullscreen mode

O código acima é autoexplicativo. os dois primeiros parâmetros são os valores e o terceiro o resultado esperado

Skip e Trait (Pular e categorizar)

Skip

Os atributos skip server para pular os testes. Às vezes você quer desativar um teste temporariamente e para isso você faz isso assim:

[Fact(Skip = "Em manutenção — aguardando correção da Calculadora")]
public void Somar_DeveLancarExcecao_QuandoOverflow()
{
    // Arrange
    var calc = new Calculadora();

    // Act & Assert
    Assert.Throws<OverflowException>(() => calc.Somar(int.MaxValue, 1));
}
Enter fullscreen mode Exit fullscreen mode

Desse modo, o teste não será executado e aparecerá no relatório como “Skipped”, com a mensagem que você colocou.

Trait

É usado pra rotular seus testes, funcionam como “tags” que ajuda a organizar e filtrar testes grandes em categorias como “tipo de teste”, “módulo”, ou “prioridade”. Por exemplo:

[Trait("Categoria", "Matemática")]
[Theory]
[InlineData(2, 3, 5)]
[InlineData(1, 1, 2)]
public void Somar_DeveRetornarResultadoEsperado(int a, int b, int esperado)
{
    var calc = new Calculadora();
    var resultado = calc.Somar(a, b);

    Assert.Equal(esperado, resultado);
}
Enter fullscreen mode Exit fullscreen mode

Marcamos a categoria como “Matemática”, mais tarde você poderá executar somente os testes dessa categoria no terminal:

dotnet test --filter "Category=Matemática"
Enter fullscreen mode Exit fullscreen mode

Outros exemplos de uso de [Trait]

Você pode usar [Trait] para indicar:

Tipo de Trait Exemplo
Categoria funcional [Trait("Categoria", "BancoDeDados")]
Nível de prioridade [Trait("Prioridade", "Alta")]
Tipo de teste [Trait("Tipo", "Integração")]

Isso facilita muito em times grandes ou em pipelines CI/CD, onde você pode rodar:

  • Só os testes rápidos (unitários) localmente
  • E todos os testes (integração, performance, etc.) no servidor

Princípio AAA (Arrange, Act e Assert)

A tradução desse princípio é organizar, agir e assertir.

Arrange: É onde preparamos tudo para o teste; onde preparamos a cena para testar (criar objetos e configurá-los conforme necessário)

Act: É onde o método que estamos será executado

Assert: É a parte final do teste em que comparamos o que esperamos que aconteça com o resultado real da execução do método de teste

Exemplo prático

Arrange (”prepare o ambiente”)

Aqui você cria os objetos, dados e dependências necessárias para o teste. Pense nele como um “palco” antes da ação. Exemplo:

var calc = new Calculadora();
int a = 2;
int b = 3;
Enter fullscreen mode Exit fullscreen mode

Act (“execute a ação”)

Aqui você chama o método ou função que está sendo testado. É o momento da ação. É importante que o teste tenha apenas uma ação principal, assim que fica claro o que está sendo verficiado. Exemplo:

var resultado = calc.Somar(a, b);
Enter fullscreen mode Exit fullscreen mode

Assert (”verifique o resultado”)

Agora é o momento de confirmar se o resultado está correto, usando os m[étodos de asserção do framework (no xUnit são os métodos da classe Assert). Se o resultado for diferente do esperado, o teste falha. Exemplo:

Assert.Equal(5, resultado);
Enter fullscreen mode Exit fullscreen mode

Exemplo completo no formato AAA

[Fact]
public void Somar_DeveRetornarResultadoCorreto()
{
    // Arrange
    var calc = new Calculadora();
    int a = 2;
    int b = 3;

    // Act
    var resultado = calc.Somar(a, b);

    // Assert
    Assert.Equal(5, resultado);
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)