Café Ágil
Sábado passado (dia 15/05/2010) participei do evento Café Ágil promovido pela ThoughtWorks Brasil no Centro de Informática da UFPE. Neste evento eu apresentei o trabalho "TDD Direto das Trincheiras", mesmo trabalho que já havia apresentado no evento Agilidade na Prática em Novembro de 2009. Naquela oportunidade, deixei pra fazer a apresentação em cima da hora e ficou bem nojentinha (veja aqui), desta vez pedi ajuda a Jinmi Lee, que deu uma reformulada no ppt. Vejam a diferença:
Para uma comunicação eficiente é necessário que tanto o contéudo quanto a apresentação sejam bem feitos. Apenas com a união desses dois fatores será possível passar a mensagem de forma eficaz.
Voltando ao evento, as apresentações de Paulo Caroli e Jim Webber foram ótimas e a participação do público foi bem legal. Bastante interessante também a mesa redonda (a mesa era retangular mesmo), que além da minha presença e a do Paulo, ainda contou com a participação de Luciano Felix (Provider Sistemas), Cristine Gusmão (UFPE) e Alexandre de Vasconcelos (UFPE). Parabéns a todos pela organização e espero que tenha mais eventos desse nível por aqui.
TDD direto das trincheiras
Essa foi a apresentação que fiz no evento "Agilidade na Prática" em 30/11/2009. Este evento foi promovido pelo SPIN Recife.
DbUnit x Hibernate
Aqui na empresa, temos clientes que apenas mandam executar um projeto segundo a arquitetura definida por eles. Algumas vezes é frustante trabalhar neste tipo de projeto, afinal, nem sempre conseguimos seguir nossas convicções e utilizar plenamente nossos conhecimentos e experiência na definição da melhor solução para o problema. Em um desses projetos, fui convocado para auxiliar a equipe que estava consumindo muito tempo na implementação dos testes.
O Cenário:
O sistema utiliza EJB 2 e Hibernate 2. O cliente exige implementação de testes dos métodos da fachada utilizando JUnit e DbUnit.
Problemas:
A montagem dos cenários é complexa. O DbUnit entende apenas o modelo relacional, isto significa que o engenheiro tem que fazer um "desmapeamento hibernate" na cabeça dele para montar as tabelas e colunas com os valores necessários. Veja um exemplo:
<dataset>
<employee start_date="2001-01-01"
first_name="Drew"
ssn="333-29-9999"
last_name="Smith" />
<employee start_date="2002-04-04"
first_name="Nick"
ssn="222-90-1111"
last_name="Marquiss" />
<employee start_date="2003-06-03"
first_name="Jose"
ssn="111-67-2222"
last_name="Whitson" />
</dataset>
Claro que esse é um modelo relacional simples, agora imagine modelos de classes complexos, com heranças, relacionamentos, etc. Neste caso, dá bastante trabalho.
Além da dificuldade em produzir a massa de dados, existe um problema muito grave. Dentro das classes de teste é necessário fazer validações contra os valores do arquivo xml (por exemplo em métodos de consulta). Neste caso podemos fazer as validações com valores hard coded, como neste exemplo:
assertEquals(employee.getFirstName(), "Jose");
Que é uma péssima idéia, pois viola o princípio DRY (Don't Repeat Yourself). Outra saída é obter os valores do xml através da API do DbUnit, que vai dar uma trabalheira danada, ainda mais se você quiser montar o objeto para fazer comparações deste tipo:
assertEquals(employeeActual, employeeExpected);
Já imaginou? Vai ter que construir outro hibernate só para pegar cada valor das tabelas e colunas do arquivo XML e remontar os objetos novamente.
Como Resolver?
O grande problema dessa abordagem é o fato do DbUnit entender apenas de tabelas e colunas. E se existisse um HibernateUnit? No hipotético HibernateUnit eu poderia especificar meus dados na forma de objetos. Além disso, poderia utilizar um formato mais legível e que pudesse ser transformado diretamente para objetos dentro do seu código. Esse formato pode ser o YAML. Veja como ficaria:
- &engineering
id : 1
name : Engineering
employees:
- id : 1
startDate : 2001-01-01
firstName : Drew
lastName : Smith
ssn : 333-29-9999
departament : *engineering
- id : 2
startDate : 2002-04-04
firstName : Nick
lastName : Marquiss
ssn : 222-90-1111
departament : *engineering
- id : 3
startDate : 2003-06-03
firstName : Jose
lastName : Whitson
ssn : 111-67-2222
departament : *engineering
Inclui um relacionamento para employee só para ficar um pouco mais rico. A vantagem dessa abordagem é que além de ficar mais legível, existem frameworks que serializam e deserializam esse formato para objetos. Com esse recurso, seria possível obter os objetos diretamente do arquivo e em seguida fazer comparações com objetos obtidos no banco. Legal, hein?
Acho que uma solução deste tipo poderia trazer muitos benefícios para o nosso problema. Estou fazendo uma pesquisa e se não existir nada semelhante, devo implementar essa solução como um projeto open source.
Pena que nosso cliente EXIGE que usemos o DbUnit.