Borba on Software Desenvolvendo Software com Qualidade.

20May/100

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.

8Mar/100

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.

11Sep/082

DbUnit x Hibernate

testingAqui 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:

<?xml version='1.0' encoding='UTF-8'?>
<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:

departaments:
    - &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.