O contato com Scrum, XP e Agile em geral, me levaram à diversos conceitos que até então desconhecia, um dos quais resolvi me aprofundar  foi TDD (Test Driven Devolpment), para isso li o livro ”Test-Driven Development by Example” escrito por Kent Beck. O Livro é muito esclarecedor e divertido de ler, apresenta diversos conceitos e técnicas através de exemplos de implementações de pequenas soluções.

TDD ou Desenvolvimento Dirigido por Testes, é uma técnica de desenvolvimento de software que consiste em pequenas iterações onde testes são escritos primeiro e o código  produzido é somente o necessário para fazer o teste passar, e finalmente o código é refatorado para acomodar as mudanças. TDD proporciona feedback rápido depois de cada mudança.  Não é considerado somente  uma técnica de escrita de testes, mas uma técnica para design de software.

chemistry por tschoppi

chemistry por tschoppi

TDD pode ser facilmente explicado em cinco simples passos:

  1. Adicione um teste rapidamente.
  2. Execute todos os testes e observe o novo teste falhar.
  3. Faça uma pequena mudança para fazer o teste passar .
  4. Execute todos os teste e observe que foram bem sucedidos.
  5. Refatore e remova o código duplicado.

Para melhor entender este ciclo de cinco fases, vamos constuir um pequeno programa Java para realizar um simples cálculo de potência. Para executar os testes precisamos de uma ferramenta de testes unitários, utilizaremos o JUnit.

O JUnit possui uma classes chamada TestCase, a qual nossa classe de teste deverá extender. Essa classe possui uma série de métodos que nos auxiliarão no processo de testes unitários, tais métodos fazem o teste falhar caso determinadas condições não sejam satisfeitas.

Ex: O método “AssertEquals(x,y)“  faz o teste falhar caso x seja direferente de y.

  assertEquals(“TDD”,”DDD”); //Falha
  assertEquals(100, 100); //Passa

Começaremos então pelo teste:

  public class CalculadoraTest extends TestCase {
    public void testCalcularOitoAoQuadrado(){
      Calculadora calculadora = new Calculadora();
      assertEquals(calculadora.calcularPotencia(8, 2), new BigDecimal(“64”));
    }
  }

Se tentarmos executar nosso teste, o JUnit nos apresentará uma barra vemelha o que signfica que o teste falhou, e falhou porque a classe Calculadora e o método estático calcularPotencia ainda não existem. Vamos então criar a classe e o método para fazer o teste ao menos compilar.

  public class Calculadora {
    public void calcularPotencia(Integer a, Integer b){
      return null;
    }
  }

Nossa missão agora é fazer, rapidamente, o teste passar. Para isso vamos então retornar o valor que nosso primeiro teste espera, 64.

  public class Calculadora {
    public void calcularPotencia(Integer a, Integer b){
      return new BigDecimal(“64”);
    }
  }

Se executarmos o teste novamente o mesmo passará… Eu seu, eu sei, que isso pode parecer meio estranho no inicio, mas não se assuste, você se acostumará e entenderá melhor o que está por traz disso tudo com o tempo. Vamos adicionar mais um método de teste em nossas classe de testes

    public void testCalcularDoisAoCubo(){
      Calculadora calculadora = new Calculadora();
      assertEquals(calculadora.calcularPotencia(2, 3), new BigDecimal(“8”));
    }

E vamos fazer a alteração mais simples possível para fazer o teste passar:

  public class Calculadora {
    public void calcularPotencia(Integer a, Integer b){
      if (b == 2)
        return new BigDecimal(“64”);
      else
        return new BigDecimal("8");
    }
  }

Agora que os dois testes estam passando, realizaremos o processo de refatoração para remover as constantes e a redundancia do código, assegurando que o teste continue passando.

  public void calcularPotencia(Integer a, Integer b){
    BigDecimal result = new BigDecimal(a);
    for (int I = 0; I < b; I++) {
      result = result.multipliedBy(BigDecimal.valueOf(a));
    }
    return result;
  }

Pronto! Refatoramos nosso código removendo as constantes e se executarmos nossos testes verificaremos que este será bem sucedido! Este é o processo básico de TDD.

Ops!!! O que acontecerá se tentarmos executar o método executar uma potencia de um número elevado a zero? Problemas!!! Todo o número elevado a Zero é igual a 1 (Um), dessa forma devemos adicionar um novo teste que verifique se um número elevado a zero retorna 1, fazer o teste passar, refatorar e assegurar de que os outros testes continuem passando.

  public void calcularPotencia(Integer a, Integer b){
    if (b.equals(0)){
      return BigDecimal.valueOf(1);
    }
    BigDecimal result = new BigDecimal(a);
    for (int I = 0; I < b; I++) {
      result = result.multipliedBy(BigDecimal.valueOf(a));
    }
    return result;
  }
  public void testTodoNumeroElevadoAZeroDeveRetornarUm(){
    Calculadora calculadora = new Calculadora();
    assertEquals(calculadora.calcularPortencia(21, 0), new BigDecimal(“1”));
    assertEquals(calculadora.calcularPortencia(8, 0), new BigDecimal(“1”));
  }

É isso pessoal! Parece simples, mas não é fácil. Depois muito treinamento e prática em diferentes cenários isso começa a ficar mais natural e você passa a enxergar mais claramente os benefício desta poderosa técnica. Estou a disposição para esclarecimento de dúvidas. Comentários são sempre muito bem vindos.