DEV Community

Cover image for Aplicando Conceitos TDD em .NET
Alex Alves for Uai Bora Tech!

Posted on

Aplicando Conceitos TDD em .NET

O Test-Driven Development é uma prática onde desenvolve-se um projeto ou parte dele pensando, primeiramente, em testes. O próprio nome traduzido já é uma auto-explicação, Desenvolvimento Dirigido por Testes. Tal prática tornou-se popular e, consequentemente, muito utilizada devido a garantia de funcionamento e qualidade de itens de desenvolvimento entregues.

Neste contexto, surge algumas perguntas, tais como:

Qual a vantagem em desenvolver assim?

  • Maior cobertura de testes no código
  • Garantia que os requisitos solicitados funcionem
  • Qualidade do código (onde o próprio código de testes traz informações sobre a qualidade do código produzido)
  • Garantia da entrega de um produto com maior qualidade

Qual a diferença entre utilizar TDD e criar os testes após o desenvolvimento?
A qualidade final de um código está com base nos testes criados. A diferença entre a maneira que cria-se os testes está no retorno de feedback do teste para o desenvolvedor.

Se um programador começa a criar os testes primeiro, ele recebe feedback constantemente, pois o mesmo consegue dividir seu trabalho em pequenas tarefas. Onde o mesmo consegue ter os seguintes passos:

  • Escrever um teste
  • Implementar um pedaço da funcionalidade
  • Executar o teste

A cada teste escrito ele recebe um feedback. E, com isso, fica fácil de alterar o código feito.

Quando o programador desenvolve primeiro e depois, ao final, cria os testes, ele não recebeu nenhum feedback. E ao criar os testes, caso tenha que realizar alguma alteração, a mesma pode ser complexa e trabalhosa e levar um tempo maior para ser feita, custando cara.

Isso irá diminuir minha produtividade?
Onde pratica-se o TDD, obviamente o desenvolvedor irá gastar um maior tempo criando testes, mas não significa ser menos ou mais produtivo.

Tal tempo gasto, é gasto de maneira inteligente. Pois os testes criados, irão perdurar até o fim do projeto/código, ou seja, irá durar por muito tempo. E, além isso, podem ser executados a qualquer momento e quantas vezes for necessário, visando a garantia do código feito.

Também, ao criar/pensar em testes primeiro, facilita as modificações no código que for preciso, como citado acima.

Como funciona o TDD?
TDD é uma técnica de desenvolvimento baseado em um ciclo, independente da linguagem de programação, composto por passos que são:

  1. Criar um cenário de teste baseado em uma regra de negócio
  2. Criar o teste baseado no cenário
  3. Executar o teste criado (irá falhar)
  4. Escrever o código até que o teste apresente sucesso
  5. Refatorar o código desenvolvido
  6. Executar o teste novamente

Basicamente, é o que está apresentado na imagem abaixo:

Image description


🔧 Mão na massa!

Regra de negócio
Antes de tudo, é preciso ler e entender qual é a regra de negócio que será solicitada. Sendo assim, tem-se:

Dado itens de produtos, é necessário permitir o cadastro de tais itens. Onde cada produto terá as seguintes informações com seus respectivos tipos:

  • Nome [string]
  • Código do produto [string]
  • Descrição [string]
  • Valor de custo [decimal]
  • Valor de venda [decimal]

Deve-se considerar as seguintes regras, ao realizar o cadastro de algum item:

  • Os campos obrigatórios serão: 'Nome', 'Código do produto' e 'Valor de custo'
  • O campo 'Valor de custo' deve ser maior do que zero
  • A quantidade de caracteres do campo 'Nome' deve ser inferior a 100
  • A quantidade de caracteres do campo 'Descrição' deve ser inferior a 500
  • O campo 'Código do produto' deverá conter, exatamente, 6 caracteres
  • O 'Valor de venda' será calculado automaticamente, onde constituirá do 'Valor de custo' + 15% de seu valor

Cenário de teste
Dado a regra de negócio acima, necessita-se criar os cenários de teste. No caso, cria-se apenas um como demonstrativo, sendo ele:

Deve-se testar um produto válido, onde apresenta-se um item composto pelos seguintes dados:

  • Nome: Notebook Acer
  • Código: 849071
  • Valor de custo: R$ 1.843,25

Deve-se validar todos os campos, de acordo com as regras, onde o resultado deverá ser sucesso.

Construção do teste
Com o cenário de teste já definido, pode-se criar os testes via código, como é exibido abaixo:

public class ProdutoTest 
{
    [TestMethod]
    [DataRow("Notebook Acer", "849071", 1843.25)]
    public void SalvarProduto_ComDadosValidos_Sucesso(string nome, string codigo, decimal valor)
    {
        //action
        Produto produto = new Produto(nome, codigo, valor);

        //assert
        Assert.IsNotNull(produto);
        Assert.IsTrue(produto.Nome == nome);
        Assert.IsTrue(produto.Codigo == codigo);
        Assert.IsTrue(produto.ValorCusto == valor);
        Assert.IsTrue(produto.ValorCusto > 0);
        Assert.IsTrue(produto.Nome.Length <= 100);
        Assert.IsTrue(produto.Codigo.Length == 6);
        Assert.IsTrue(produto.ValorVenda == 2119.7375);
    }
}
Enter fullscreen mode Exit fullscreen mode

Analisando o código, nota-se o seguinte:

  • Para que um produto exista é necessário informar o nome, código e valor de custo do mesmo. Com isso, tais campos são cobrados no construtor da classe e a mesma não deve permitir ser instanciada sem tais campos, atendendo a primeira regra de validação.
  • É testado se o campo referente ao Valor de Custo é maior do que zero, atendendo a segunda regra de validação
  • É testado se o campo referente ao nome tem o número de caracteres menor ou igual a 100, atendendo a terceira regra de validação
  • É testado se o campo referente ao código do produto tem o número de caracteres igual, exatamente, a 6, atendendo a quinta regra
  • É testado se o campo referente ao valor da venda é igual a 2119.7375, valor obtido pela fórmula descrita na regra de negócio, atendendo a sexta regra

Execução do teste
Após o teste já estar desenvolvido, pode-se executá-lo. Como ainda não tem-se nenhum código criado, o teste não será executado e irá dar erro de compilação.

Image description

Escrita do código
Após analisar o teste criado, deve-se desenvolver o código que irá atendê-lo, ou seja, criar a classe Produto com todos os atributos esperados.

public class Produto 
{
    public Produto(string nome, string codigo, decimal valor) 
    {
        Nome = nome;
        Codigo = codigo;
        ValorCusto = valor;
    }

    public string Nome { get; }
    public string Codigo { get; }
    public decimal ValorCusto { get; }
    public decimal ValorVenda { get; } = ValorCusto * 1.15;
}
Enter fullscreen mode Exit fullscreen mode

Refatoração do código escrito
Como o código desenvolvido está atendendo perfeitamente as regras de negócio, não será necessário refatorá-lo. Apenas se houver alguma mudança na própria regra.

Execução novamente do teste
Por fim, ao executar o teste novamente, nota-se que o mesmo irá ter um resultado de sucesso.

Image description


Conclusão

Seguindo tais práticas, garante-se que o código desenvolvido sempre estará coberto por uma certa quantidade de testes. Onde, a cada alteração do código pode-se assegurar que o mesmo estará em funcionamento.

É válido, também, considerar que os teste não são imutáveis. Pois as regras de negócio podem sofrer alterações.


Referências

Top comments (0)