Coding Dojo Floripa

Desenvolvimento Ágil

Exemplo TDD, parte 1: Por onde começar

Posted by Ivan Sanchez em Quinta-feira, Novembro 9, 2006

Aviso! Todo o contexto deste exemplo é 100% fictício.
Qualquer um pode colaborar com sugestões/críticas/perguntas, então participe!

Começamos há pouco tempo um novo projeto de um sistema para controlar o acesso e acompanhar a frequencia dos estudantes de um cursinho pré-vestibular. A integração com a catraca ainda não é prioridade, então a nossa primeira tarefa é: armazenar e contabilizar as horas dos estudantes.

Nossa intenção é desenvolver orientado a testes, então surge a pergunta: por onde começar?

Como já sabemos, o primeiro passo para criação de código usando TDD é criar um teste que falhe. Embora o primeiro teste pareça sempre o mais complicado para se escrever, depois de algum treino ele acaba se tornando tão simples quanto os demais. Isso porque não há mesmo muita diferença entre eles.

Então como escrever o primeiro teste? A resposta é: não importa, desde que ele seja escrito. Não há necessidade de se preocupar se o teste está errado, uma vez que o código da aplicação sequer existe. Se ele parecer errado basta reescrevê-lo, e isso poderá ser feito em qualquer momento, mesmo depois de existirem centenas de testes.

Um teste é a descrição de um comportamento do sistema. Então basta termos uma idéia qualquer do que o sistema tem que fazer que já podemos começar.

Resolvemos começar escrevendo uma classe para representar as horas dos estudantes. Começamos com um item qualquer na nossa checklist mental:

  • Representar uma hora qualquer no formato hh:mm

Então vamos fazer o nosso primeiro teste para criar um objeto da classe Hora com um determinado valor e verificar se este foi armazendo. O código fica assim:

package dojo.exemplo.tdd;
import junit.framework.TestCase;
public class HoraTest extends TestCase
{
    public void testCriacaoHoraQuinzeHoras()
    {
        Hora hora = new Hora("15:00");
        assertEquals("15:00", hora.toString());
    }
}

Estamos especificando um comportamento esperado da nossa classe e fazemos uma validação, o que significa que nosso primeiro teste está pronto. Porém este ainda não compila porque não temos a classe Hora e seu construtor. Então chegou a hora de criá-la:

package dojo.exemplo.tdd;
public class Hora
{
    public Hora(String string)
    {
    }
}

Isso é o mínimo que precisamos para rodar o primeiro teste. E com isso temos o nosso primeiro erro:

junit.framework.ComparisonFailure: expected: but was:

Nossa tarefa agora é fazer o teste passar, e a maneira mais simples para isso é criar o método toString() na classe Hora, retornando uma constante:

    public String toString()
    {
        return "15:00";
    }

Com esta alteração o teste agora passa. Porém sentimos que ainda podemos melhorar, e para isso só temos duas alternativas válidas: fazer um refactoring ou escrever um novo teste.

Decidimos fazer um novo teste na classe HoraTest para quebrar esta primeira implementação:

    public void testCriacaoHoraDezEMeia()
    {
        Hora hora = new Hora("10:30");
        assertEquals("10:30", hora.toString());
    }

Isto já é o suficiente para fazer o teste falhar, o que já esperávamos uma vez que nossa classe não permite criar uma hora diferente de 15:00. Portanto precisamos modificá-la:

    private String hora;
    public Hora(String string)
    {
        this.hora = string;
    }
    public String toString()
    {
        return this.hora;
    }

Rodamos os nossos dois testes e agora ambos passam. E agora já é possível pensar em pelo menos mais duas classes que a classe tem que fazer:

  • Representar uma hora qualquer no formato hh:mm
  • Permitir a criação de uma hora padrão (“00:00”)
  • Não permitir que se crie hora fora do formato hh:mm

(Começaremos a próxima parte do nosso exemplo resolvendo estes dois itens)

10 Respostas to “Exemplo TDD, parte 1: Por onde começar”

  1. Roberto said

    Ivan, apenas uma sugestão, creio que seria interessante já utilizar o Junit 4.0 que dá suporte a anotações, facilitando o uso para casos que o retorno esperado são exceções.
    No guj vc pediu algumas sugestões e citou alguns tópicos e acho que para manter a simplicidade (um dos tópicos) é interessante não aplicar patterns, já que é algo muito atômico (pelo menos nos testes unitários).

    Parabéns pela iniciativa

  2. Ivan,

    Antes de mais nada, parabéns!🙂 Tem um tutorial de TDD que escrevi há algum tempo onde você também poderia coletar algumas idéias. Está no endereço: http://www.improveit.com.br/xp/praticas/tdd .
    Espero que seja útil.

  3. Leandro Zis said

    Ivan, parabens pela inicitiva.

    Ricardo, eu discordo de você quando diz que patterns aumentam a complexidade, eu acho justamente o contrario. E não entendi oq vc quis dizer com “atômico”.

  4. Roberto,

    Primeiramente, obrigado pelo feedback🙂

    Então, eu cheguei até a pensar em colocar os testes em pseudo-código, já que meu objetivo era mostrar TDD, independente da ferramenta. Acabei fazendo no jUnit 1.3.8 para facilitar os usuários do Java 1.4 (a maioria que eu conheço). Mas concordo que o jUnit 4 tem suas facilidades, e espero que eu consiga mostrá-las em breve🙂

    Quanto aos design patterns, não entendi o que você quis dizer com “atômico” neste caso. O que isso seria? A minha sugestão era para mostrar que é possível aplicar design patterns programando com TDD (principalmente buscando remover duplicações), coisa que muita gente duvida já que a modelagem é feita incrementalmente.

  5. Vinicius,

    Conheço o seu tutorial e ele com certeza foi bastante útil. Inclusive conduzi uma sessão de programação num treinamento onde reproduzíamos o seu exemplo para o pessoal treinar TDD, com resultados bem legais.

    Agora a minha idéia é partir de um exemplo mais simples ainda para coletar as principais dúvidas de quem está aprendendo TDD e tentar respondê-las a cada nova parte do exemplo que eu for publicando. Tomara que dê certo🙂 E obrigado pelos parabéns!

  6. Leandro,
    Também concordo que patterns diminuem a complexidade. Porém quando mal encaixados ou usado em excesso, eles podem acabar deixando o código mais complexo. Por isso costumo aplicá-los principalmente durante refactorings, e não durante a solução dos testes.

    Espero que eu consiga deixar estas idéias claras nas próximas partes do exemplo. Até lá obrigado pela ajuda🙂

    Ps.: O nome do cara do comentário acima é Roberto, e não Ricardo😉

  7. […] Terminamos a primeira parte do nosso exemplo com os seguintes itens para implementar: […]

  8. Raphael said

  9. camilo said

    realmente excelente post,simples e eficiente. Conseguir tirar umas duvidas de como criar o primeiro teste, sempre dar um travamento por onde começar a escrever, gostei.
    parabens! pela simplicidade na escrita e foi bastante objetivo.

    flw!

  10. blog said

    Howdy, I think your website could be having internet browser
    compatibility problems. Whenever I look at
    your website in Safari, it loooks fine but when oplening in I.E., it has sme overlapping issues.
    I just wanted to give you a quick heads up! Other thwn that, fantastic website!

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

 
%d bloggers like this: