DEV Community

Alessandra Souza
Alessandra Souza

Posted on

4 2

Teste de Unidade

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.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (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

Feliz que tenha gostado ;-)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay