Codeblox Blog

Categorize seus testes com atributos customizados no xUnit

Guilherme
23/10/2022

Categorizar os testes pode ser uma ferramenta útil para organizar e filtrar os testes que deseja executar em determinados momentos. O xUnit oferece o atributo [Trait("Chave","Valor")] para isso.

Mas e se pudéssemos usar atributos customizados, por exemplo: [Category("Integrado")] ou [Integrado]. Saiba que é possível e vou explicar como fazer isso.

Implemente um TraitDiscoverer

Primeiro é necessário criar uma classe que implemente a interface ITraitDiscoverer. Esta classe vai determinar quais conjuntos de Chave/Valor de Trait serão aplicados quando seu atributo customizado for utilizado em um teste.

Vamos supor que seu atributo customizado será assim: [Category("NomeDaCategoria")].

Então o seu discoverer será implementado da seguinte forma:

using Xunit.Abstractions;
using Xunit.Sdk;
namespace MeuNamespace;
public class CategoryDiscoverer : ITraitDiscoverer
{
  public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)
  {
    // Obtém o nome da categoria utilizado no atributo
    var categoryName = traitAttribute.GetConstructorArguments().First().ToString();
    // Retorna o par Category/categoryName
    yield return new KeyValuePair<string, string>("Category", categoryName);
  }
}

Implemente o atributo customizado

Agora implemente o atributo [Category], note que ele contém uma anotação que indica qual o Discoverer correspondente, através do atributo [TraitDiscoverer]:

using Xunit.Sdk;

namespace MeuNamespace;

// Parâmetro 1: Nome completo do tipo do discoverer
// Parâmetro 2: Nome do assembly que contém o discoverer
[TraitDiscoverer("MeuNamespace.CategoryDiscoverer", "MeuNamespace")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CategoryAttribute : Attribute, ITraitAttribute
{
    public CategoryAttribute(string category) { }
}

Utilize o atributo customizado

Utilize o seu atributo customizado nos testes que desejar, ex:

public class ServiceTests {
    [Fact]
    [Category("Slow")]
    public void ServiceDeveFuncionarCorretamente(){
        ...
    }
}

Assim como o uso do atributo [Trait] nativo do xUnit, os atributos customizados funcionam perfeitamente no visualizador de testes do Visual Studio. Já no Rider, infelizmente parece não funcionar.

Para filtro de testes também funciona sem problemas. Eu costumo usar durante validação de PRs, para filtrar testes integrados a serviços externos que podem estar indisponíveis no momento.

Ex:

dotnet test --filter Category!=Slow

dotnet
devops
qualidade


Guilherme M. Abdo
Guilherme M. Abdo
Desenvolvedor fullstack .Net/Angular/Azure/GitHub