Japybara – testes funcionais e de integração para java
Faz muito tempo que tenho uma preocupação muito grande com testes automatizados.
Meu primeiro contato foi, obviamente, com o JUnit, ainda em 2001. O que mais me encantou foi a possibilidade de aniquilar um fantasma que assusta muita gente: o “eu juro que já tinha testado!”.
Quantas vezes não fiquei com carão ao ver um bug que, sim, eu já tinha corrigido, mas ele teimava em voltar. Ou ainda mais simples: um bug desconhecido (e óbvio) sobre uma funcionalidade que já tinha sido bem testada, mas que quebrou por um efeito colateral qualquer.

Assim, a primeira coisa que me pegou foi a possibilidade de ter testes de regressão. Mas, obviamente, não foi a única. Junto com isso veio outras coisas, como o TDD, suporte a refactoring de gente grande, segurança, explorações, etc.
assertNotFrustrated(expected, actual)
Mas aí vieram duas coisas chatas: o container chato e o teste fraco.
No início, meus primeiros testes eram executados em segundos, como um “Run” de dentro do IDE. Mas os containers com seu processo lento e mais ou menos manual de “deploy” os enfraqueceu e complicou. E aí fiquei de novo com cara de taxo. Mesmo tendo um monte de casos cobertos em testes unitários, eu era surpreendido com erros na aplicação “deployada”, que vinham de todos os lados:

- Erro no template, como um null pointer em um
${user.name}, quandousernão havia sido definido. - Erro também no template, mas proveniente do HTML/CSS usado.
- Mais erro no view, desta vez de javascript.
- Erro de configuração no ambiente interno.
- Erro de configuração do ambiente externo (integração/pre/produção).
- E por último, mas não menos, casos de teste que eu só imaginava à medida em que interagia com a aplicação. Este é o que mais dói, pois você pode descobrir um mundo de situações se você se fechar naquele esquema eu-sou-foda-porque-faço-100%-de-cobertura. É aí que a tartaruga passa o coelho presunçoso. É aí que você ouve o uncle Ben.
No Chile
Mesmo assim, sou ferrenho adepto desta técnica que, obviamente imperfeita, pode ajudar muito se bem utilizada. Foi por isso que quero levar isso para a turma que foi contratada pela Gonow, no Chile. Mas, para fazer um negócio mais bonitinho, resolvi preparar um roteiro para passar para o pessoal.
E eis que começo a fazer uns testes muito sem graça. Tipo, que graça tem um teste de um container/controller do VRaptor, quando a lógica de negócio é muito chinfrim? Ou quando o que pega é a configuração do ambiente?
Então eu resolvo fazer um teste que sai da configuração e vai ao view. Mas sem ter que ficar subindo e baixando tomcat, que é muito chato. Ou melhor: sem precisar instalar o dito-cujo, como um mvn jetty:run da vida. Ou ainda mais prático: com um clique no botão de executar os testes. Para isso, eu só preciso subir o jetty-embedded, já devidamente configurado, antes dos testes (à la um @Before). E depois é matar o dito-cujo.
Aumentar a segurança dos testes, ao mesmo tempo em que simplifica e acelera o processo?
Japybara – na falta de um nome melhor
Pensei bem e resolvi colocar tudo numa biblioteca. Fechei o projeto-roteiro-para-tdd e criei o japybara. O nome veio do Capybara, que é algo que já penso em passar para o pessoal faz tempo. Só que para java.
A coisa toda é muito simples.
- Baixe o japybara do github: git://github.com/gandralf/japybara.git
- Instale-o em seu repositório: mvn install. Cuidado: por enquanto os testes usam a porta 8080.
- Adicione isso ao pom do seu projeto:
<dependency> <groupId>org.japybara</groupId> <artifactId>japybara</artifactId> <version>0.1</version> <scope>test</scope> </dependency> - Crie sua classe de testes:
import org.junit.Test; import static org.junit.Assert.*; import org.japybara.WebTest; public class SomeWebTest extends WebTest { @Test public void shouldHit() throws IOException { visit("/hello?name=John"); assertHasContent("Hello, John!"); } } 
Observação: usei o termo “testes de integração” aqui como um genérico para algo maior que os testes unitários. Dependendo do contexto, você pode usar o Japybara para os testes funcionais e de aceitação.