O desenvolvimento orientado a testes, como qualquer prática, necessita de tempo e dedicação, pois a cultura atual diz para construir e testar (se der tempo), nesta ordem. Não raro, construímos vários componentes e só depois testamos.
Invertendo esta ordem, em primeiro lugar, aumentamos a importância do teste, garantido que sempre seja escrito. Em segundo lugar, aumentamos a confiança no que estamos fazendo e, assim, melhoramos frequentemente a implementação, pois não temos mais medo de alterar.
A teoria é mais simples que a prática. O grande desafio do TDD é aprendermos a escrever bons testes. É neste ponto que entra a experiência. Quando os testes estão cobrindo a funcionalidade de forma eficiente, temos uma boa suite para aquele requisito do usuário.
Ao escrever os testes, precisamos pensar em mais que na correção do requisito, isto é, precisamos testar os limites, todas as condições de um if, fazer passar em laços, condições de exceção, etc. Para isso, precisamos calcular bem os inputs, garantindo que informações consistentes estão sendo passadas para a aplicação.
E é justamente estas técnicas que mostrarei aqui, com um dos requisitos de um sistema que estou desenvolvendo como free-lancer, com uma equipe composta de quatro pessoas, sendo uma delas, o dono do produto. O sistema consiste em processos de leitura de informações para um sistema de monitoramento baseado em GPS. Tenho boa experiencia com este tipo de sistema, já que trabalhei três anos consecutivos com uma ampla variedade de satélites e sistemas, quando fui o responsável pela área de desenvolvimento de uma empresa especializada neste tipo de serviço.
O requisito que escolhi foi a leitura da data da mensagem. A implementação da leitura será omitida. Na verdade, creio que esta omissão não prejudicará o objetivo deste texto, que deve focar em como testar.
Bem, para ler a data de geração da mensagem precisamos, inicialmente, garantir que existe mensagem. Assim:
@Test(expected=IllegalArgumentException.class)
public void recusarMensagemSemCaracteres() {
final Rastreador people = People.getRastreador("");
people.lerDataDeGeracao();
}
O proximo teste garante que o texto informado tenha a quantidade de campos necessária para a leitura da data de geração:
@Test(expected=IllegalArgumentException.class)
public void recusarMensagemComMenosDe15PartesSeparadasPorVirgula() {
final Rastreador people = People.getRastreador("abc");
people.lerDataDeGeracao();
}
public void recusarMensagemComMenosDe15PartesSeparadasPorVirgula() {
final Rastreador people = People.getRastreador("abc");
people.lerDataDeGeracao();
}
No próximo, garantimos que seja recusada uma mensagem sem a data com o formato esperado, na posição esperada:
public void recusarMensagemSemDataNoFormatoEsperadoNaUltimaParte() {
final String mensagem = "357566000009224 $GPRMC,120111.00,V,2300.52128,S,04321.95074,W,3.185,301.85,030911,,,A*78,V=3.438(LP),Device BATTERY LOW!!!";
final Rastreador people = People.getRastreador(mensagem);
people.lerDataDeGeracao();
}
E, finalmente, no ultimo teste desta suite, garantimos que conseguimos ler a data de geração:
@Test
public void recuperarDataDeGeracao() throws ParseException {
final String mensagem = "357566000009224 $GPRMC,120111.00,V,2300.52128,S,04321.95074,W,3.185,301.85,030911,,,A*78,V=3.438(LP),Device BATTERY LOW!!! 2011/9/3 ?? 12:01:11";
final Rastreador people = People.getRastreador(mensagem);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date dataEsperada = sdf.parse("03/09/2011 12:01:11");
Date dataObtida = people.lerDataDeGeracao();
Assert.assertEquals(dataEsperada, dataObtida);
}
Como líder técnico deste projeto, foi fácil implantar a cultura do TDD e, com isso, mostrar ao time, na prática, os benefícios de testar antes. Entretanto, outra grande vantagem do TDD é a sua aplicabilidade. Aprovação de ninguém é necessária. A única necessidade é garantir que você está entregando a mesma quantidade de funcionalidades que entregava antes. Com prática no desenvolvimento orientado a testes, é possível, em pouco tempo, começar a entregar mais com menos quebras (bugs) sendo assim, mais eficiente.
Na minha visão, um dos grandes prazeres de praticar o TDD é descobrir testes que possam aumentar a confiança no que está sendo implementado.