DEV Community

loading...

Teste de Unidade

Alessandra Souza
Sou uma dev backend apaixonada pela natureza ;-)
・3 min read

Teste de Unidade: É o teste da menor unidade testável de um programa.

Em português é comum falar teste unitário, porém o mais correto é o termo teste de unidade. Teste unitário da a sensação que é apenas um teste, no entanto podemos criar vários cenários para testar o seu método.

Um teste de unidade precisa ser:

  • Rápido: Não é incomum para projetos maduros ter milhares de testes de unidade. Os testes de unidade devem levar muito pouco tempo para serem executados. Milissegundos.

  • Isolado: Testes de unidade são autônomos e não têm dependências de nenhum fator externo, como um sistema de arquivos ou o banco de dados. Mesmo um teste de integração, as dependências externas são resolvidas com o uso do InMemoryDataBase ou com mocks.

  • Repetível: A execução de um teste de unidade deve ser consistente com seus resultados, ou seja, ele sempre retornará o mesmo resultado se você não alterar nada entre execuções. Se o teste hora passa, e hora não, talvez ele esteja compartilhando estado de algum objeto.

  • Verificação automática: O teste deve ser capaz de detectar automaticamente se ele foi aprovado ou reprovado sem nenhuma interação humana.

  • Em tempo hábil: Um teste de unidade não deve levar muito tempo para ser escrito comparado com o código que está sendo testado. Se você demorar muito tempo para escrever o teste, considere um design mais estável ou um refactoring.

Como nomear os Testes?

Modelo 01:
ObjetoEmTeste_MetodoComportamentoEmTeste_ComportamentoEsperado
Ex: Pedido_AdicionarItem_DeveExibirErroSeItemJaAdicionado

Modelo 02:
MetodoEmTeste_EstadoEmTeste_ComportamentoEsperado
Ex: AdicionarItem_ItemJaExistente_DeveExibirErroSeItemJaAdicionado

Padrão AAA

O padrão AAA auxilia na organização do teste e deixa ele mais legível.

Arrange: onde é preparado os objetos para serem testados.
Act: onde fica a ação a ser executada.
Assert: onde ficam as comparações.

Evite usar os métodos de Setup e Teardown para criar objetos utilizados no teste, assim você terá:

  • Menos confusão ao ler os testes, uma vez que todo o código está visível dentro de cada teste;
  • Menos chance de configurar demais ou de menos para o teste específico;
  • Menos chance de compartilhar o estado entre os testes, que cria dependências indesejadas entre eles.

Evite o uso de mais de um assert no teste, pois assim você garante que não está declarando vários cenários no mesmo teste.

Uma exceção a regra é um assert sobre propriedades de um objeto.

Frameworks para teste

  • MsTest: Desenvolvido pela Microsoft.
  • nUnit: Desenvolvido e mantido pelo .Net Foundations.
  • xUnit: Desenvolvido pelos mesmos criadores do nUnit e é o mais recente framework para testes.

Segue comparação entre os frameworks no link.

Apesar da Microsoft ter desenvolvido o MsTest, atualmente ela recomenda o uso do xUnit.

Exemplos com xUnit

Vamos ver agora alguns exemplos de teste de unidade, usando o framework xUnit e os padrões de nomenclatura e organização dos testes.

O teste abaixo verifica se um cpf é válido.

[Fact]
public void SocialNumber_IsValid_ReturnTrueForValidValue()
{
    //Arrange          
    //Act
    var result = SocialNumber.IsValid("52812349000");

    //Assert
    Assert.True(result);
}
Enter fullscreen mode Exit fullscreen mode

No xUnit para testar mais de um valor pode-se utilizar o Theory, assim seu teste fica mais limpo.

O teste a seguir verifica se cada cpf informado no InlineData é válido.

[Theory]
[InlineData("557.287.970-32")]
[InlineData("016.118.090-61")]
[InlineData("143.504.220-48")]
[InlineData("660.352.030-35")]
[InlineData("93355758019")]
[InlineData("77228802071")]
[InlineData("24780314003")]    
public void SocialNumber_IsValid_ReturnTrueForValidValues(string value)
{
    //Arrange          
    //Act
    var result = SocialNumber.IsValid(value);

    //Assert
    Assert.True(result);
}
Enter fullscreen mode Exit fullscreen mode

Para finalizar, um exemplo testando exceções.

O teste a seguir, verifica se uma determinada exceção é lançada ao informar um valor nulo.

[Fact]
public void SocialNumber_Constructor_ThrowsExceptionForNullValues()
{
    //Arrange          
    //Act   
    //Assert
    var ex = Assert.Throws<ArgumentNullException>(() => SocialNumber.FromString(null));
    Assert.Equal("Value cannot be null. (Parameter 'value')", ex.Message);
}
Enter fullscreen mode Exit fullscreen mode

Caso queira ver o código completo, segue o link do GitHub.

Referências

Recomendo a leitura deste artigo da Microsoft. Nada melhor do que beber a água direto da fonte.

https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices

Se quiser se aprofundar mais no assunto, também recomendo o curso "Dominando os Testes de Software" do Eduardo Pires na plataforma https://desenvolvedor.io.

Discussion (2)

Collapse
eduardoklosowski profile image
Eduardo Klosowski

Gostei bastante das definições e da descrição de como organizar os testes, que discute sobre o setup e teardown, achei interessante.

Collapse
alsouza93 profile image
Alessandra Souza Author

Feliz que tenha gostado ;-)