Palestra: Testes de Unidade com JUnit

Hoje tivemos mais um encontro do ESJUG. Desta vez eu fiz uma apresentação sobre Testes de Unidade com JUnit. A idéia principal da apresentação foram os exemplos, mas os slides ficaram legais, por isso estou compartilhando.


Estou preparando os códigos que foram feitos na apresentação junto com outros que foram preparados antes para demonstração. Depois que estiver ‘organizado’ vou subir para o github e disponibilizar aqui no blog.

Integração contínua é com TeamCity

Recentemente fui convidado a montar o ambiente de integração contínua de uma empresa. O trabalho inicial de verificação dos projetos, testes e builds existente foi feito como manda o figurino. Todos os projetos usavam maven2 e, felizmente, todos eles (inclusive os sub-projetos) possuíam pom’s bem configurados e completamente funcionais.

Os builds e processos internos (manuais) para builds da empresa estavam ok, verificados e funcionando. Feito isso fomos aos testes. Testes!? Ok, vamos ao próximo passo e esqueça os testes por enquanto. O controle de versão era feito com Subversion e os clientes usando Tortoise. A IDE utilizada por toda a organização era o IntelliJ IDEA, mesmo assim o cliente para o SVN era o Tortoise, ainda tento compreender isso até hoje.

wheresthebuild-smallA empresa estava em um momento de criação e manutenção de testes funcionais, então, algumas pessoas estavam trabalhando exclusivamente com Selenium. Era uma boa oportunidade, pois estes testes seriam todos automatizados no ambiente de integração contínua a ser preparado. Uma série de procedimentos foram realizados até chegarmos no ambiente de facto, mas vou pular isso para o post não ficar grande e chato de mais.

Comecei então com a preparação de alguns protótipos. Já trabalhei algumas vezes em ambientes de integração contínua com o CruiseControl e também com o CruiseControl.rb, logo pensei em utilizar um desses. Pesquisando e perguntando a conhecidos cheguei às indicações de: Hudson com muitas indicações, Continuum da Apache, TeamCity da JetBrains e Bamboo da Atlassian, sendo estes dois últimos privados e com custo para licença. Ainda assim estava considerando as duas alternativas pagas logo depois de alguma alternativa da família CC, isto porque a empresa possuía licenças do Jira e Confluence, logo o Bamboo poderia ser uma boa pedida devido a recursos de integração. E também possuíam licenças do IntelliJ IDEA, logo a integração com a IDE poderia ser um ponto positivo para o TeamCity.

Alguma coisa aconteceu comigo e na manhã seguinte eu resolvi começar pelas ferramentas que eu não conhecia. Comecei pelo Hudson, TeamCity e por último Continuum, resolvi parar por aqui pra não perder mais tempo, nesse momento já havia uma escolha muito clara e três dias já haviam se passado.

Continue lendo “Integração contínua é com TeamCity”

E a qualidade, como você garante?

Durante minhas apresentações sobre Testes de Software existem algumas perguntas que são clássicas, sempre fazem no mínimo uma delas. Por exemplo:

  • Mas com testes, demora mais?
  • E se demora mais, não fica mais caro?
  • E se demora mais e fica mais caro, por que testar?
  • Como eu vou mostrar para o meu cliente um relatório de execução de testes? Pirou!?

Pra quase todas eu respondo sim. Sim, simplesmente escrevendo testes ou trabalhando com TDD/BDD é um pouco mais demorado (medindo exclusivamente em tempo) sim, principalmente no começo de um projeto. Podemos pensar que se demora mais, inicialmente, também fica mais caro, afinal de contas, tempo é dinheiro. Mas depois deste movimento inicial e saindo da inércia o fator de tempo se inverte e o desenvolvimento no projeto torna-se mais rápido e mais barato. Assim como a manutenção do projeto.

Após responder sim para esses questionamentos, intencionalmente, eu inicio a discussão com uma pergunta, desta vez sou eu quem pergunto ao congressista: Como você garante a qualidade do seu produto?

Eis que então abro as portas para chegar no ponto principal desta apresentação sobre Testes de Software, conscientizar as pessoas de que é necessário testar, pois, esta é a forma menos dolorosa para mantermos não só a qualidade, mas também a vida dos nossos produtos. Mesmo assim eu sempre tomo cuidado para não vender a idéia de que testes são a solução pra tudo, muito menos que pelo simples fato de escrever testes para todas as funcionalidades do seu sistema que ele não terá bugs ou problemas, muito pelo contrário. Mas então por que testar? Pois até hoje, testar é a forma mais barata e eficiente que encontramos para evitar que os problemas cheguem ao cliente/usuário. Eis então aí a qualidade do seu produto. E quando eu deixo de falar em “testes” para falar de “qualidade” eu consigo a atenção de todos, inclusive de quem não irá escrever testes, mas quem decidirá se o desenvolvedor terá espaço para escrever testes ou não, os gestores/líderes.

Geralmente quando você não escreve testes qual é a forma utilizada para garantir que o que será entregue ao cliente está funcionando de acordo com o que foi especificado (comportamento)? Não sabe responder!? Bom, então como você faz para garantir que o produto ao menos funciona, esqueça aqui o modelo de negócios, as telas ao menos abrem? O usuário não vai receber nenhuma NullPointerException na cara? Também não sabe responder!? Não tem segurança para responder!? Não fique triste, infelizmente tem muita gente na mesma situação que a sua.

Na maioria das vezes os projetos de software começam com funcionalidades e datas de entrega pré-definidas, contratos rígidos, multas astronômicas, e o pior, fases pré-definidas: requisitos de sistemas, requisitos de software, análise, design, codificação, testes e implantação. Acho que não preciso falar muito do modelo em cascata, o que todos sabemos é que as fases iniciais sempre são feitas pelos “analistas de sistemas” da empresa, na maior moleza gastando mais da metade do tempo e verba do projeto sem gerar nada de útil para o desenvolvimento. O que acontece? Os desenvolvedores simplesmente chutarão os testes (e muitas outras coisas) pois: – não temos tempo agora; – depois eu testo; – a entrega é daqui a 15 dias; – está funcionando sem testes. E o pior, tentarão justificar a ausência de testes devido a este modelo cultural e organizacional falho.

Então o projeto, de fato, começa. Mas e os releases, como ficam? Como você garante que o que será entregue ao seu cliente está funcionando? E que está atendendo a tudo que ele especificou? (estou me repetindo, eu sei, mas é por uma boa causa). Melhor, se sua equipe trabalhou na correção de um bug ou na implementação de uma nova feature, como você garante que o que foi feito está ok e que todo o restante continua funcionando como antes? Certamente o seu cliente não espera que você entregue um relatório de execução da sua suite de testes, mas ele também não espera que você entregue um certificado de garantia ou algo parecido, ele simplesmente confia em você e espera que você faça por merecer.

E você no começo faz questão de parar um desenvolvedor ou analista para testar a funcionalidade que está sendo desenvolvida, ele executa a aplicação, faz um caso que funciona e outro que não funciona, te responde ok em cerca de 45 minutos. Passam-se alguns dias e já existem 5 funcionalidades, o mesmo desenvolvedor vai testar e te da ok em cerca de 4 horas ou mais. Mais algumas semanas e ele já não testa mais todos os casos, só os que funcionam e eventualmente pula uma ou outra funcionalidade pra terminar os testes mais rapidamente, depois de 3 dias ou mais ele te da o ok. Imagine depois que o sistema estiver grande (é mania das empresas querer fazer sistemas gigantes), você vai parar um desenvolvedor por duas semanas ou mais para testar? Ou você vai manter uma equipe de “testadores”? E como você vai explicar as regras de negócio de um sistema de controle de transações comerciais para 5 ou 6 novos funcionários para depois testarem o seu produto? Será que eles saberão o que fazer e como fazer? Pense em muitos problemas aqui.

Essa prática é demorada. Se acontecer (e vai acontecer) um problema seríssimo em produção e você precisar corrigir e entregar rápido, no mesmo dia, como você vai fazer para testar todo o resto do sistema em algumas horas? Certamente você vai pensar (e rezar) que esta alteração foi pontual e que não afetará mais nada no sistema e vai entregar sem testar. Se as novas solicitações forem de features pequenas você não vai querer testar todo o sistema, não vai se preocupar em fazer um teste de regressão, e vai, novamente, rezar e fazer promessas acreditando nos poderes sobrenaturais dos seus desenvolvedores. E o pior é que se alguma vez isso funcionar, esta poderá se tornar uma prática comum na empresa: alterou; compilou? Então está pronto, pode entregar ao cliente.

Se você precisar economizar ou cortar custos, a primeira equipe a dançar será a de “testadores” ou se ela não existir, será o tempo gasto pelo desenvolvedor que fazia os testes manuais. E com isso você não cortará somente custos, nesta altura do campeonato este é o seu menor problema, ou deveria ser a sua menor preocupação, você estará cortando diretamente a qualidade do seu produto! E sem qualidade a confiança que o seu cliente tem em você começará a diminuir, a imagem da sua empresa junto ao cliente começará a perder o brilho e num determinado momento o cliente se dará conta que você entregou o produto em 4 meses e está a 2 anos tentando deixá-lo totalmente funcional, sem muito sucesso.

Não são somente os testes automatizados que irão garantir a qualidade do seu produto, você tem outras alternativas e a mais conhecida são os testes manuais feitos pelo desenvolvedor ou por sua equipe de testadores, porém esta não é uma alternativa barata e nem rápida, isso não é sustentável ao longo da vida de um projeto.

Se você e seu cliente não se importam em esperar 15 dias para uma release sair, tudo bem, não escreva testes; se você não se importa com o alto custo de manter uma dúzia de pessoas para preencher campos e dar ok, tudo bem, continue sem testes; se o seu cliente te paga 5 vezes mais para fazer o produto funcionar do que o ele pagou para ter o produto, tudo bem também, continue sem testes; ou se os seus desenvolvedores são especiais e possuem poderes além da nossa compreensão e isto permite que você não teste, ótimo, você é um sortudo, pode continuar assim. Se alguma forma sem testes automatizados funciona pra você e você consegue garantir qualidade assim e ainda consegue ser uma organização lucrativa, sorte a sua (e coitado do seu cliente). Só que as coisas nem sempre são assim.

Você deve verificar o seu código, sempre! Você deve testar rápido, pois precisa entregar rápido. Você deve ter segurança para alterar, pois sua equipe pode ser nova ou com pessoas que não conhecem o projeto. Você precisa testar tudo o que foi alterado e todo o resto para saber se algo não deixou de funcionar com alguma alteração. E você precisa fazer tudo isso pra ontem, afinal, você está no mesmo planeta que o resto das pessoas.

Se no início do projeto você tivesse feito o que era necessário, se tivesse investido em testes e automatizado todos eles, após a entrega do produto você poderia dedicar os próximos 2 anos que iria passar dando manutenção em código legado (lembre-se que código sem testes já nasce legado) prospectando novos clientes e projetos. Se aqueles minutinhos para escrever os testes não tivessem sido cortados, hoje, quando o produto tiver milhões de linhas de código e centenas de funcionalidades, após uma alteração qualquer, feita por um estagiário que chegou ontem e nem conhece o produto, você conseguirá saber em questão de minutos (ou no máximo horas) o resultado e impacto desta alteração, com um simples click você saberá se pode entregar a release para o cliente, ou não.

Ao final do projeto, sim, este projeto terá um fim e será concluído de verdade, aquele tempinho que parecia estar sendo perdido com testes, pensando que testar uma funcionalidade antes mesmo dela existir é coisa de maluco, pensando que o melhor a se fazer é correr e correr e correr pra entregar logo qualquer coisa ao cliente, tudo isso vai se converter num ganho inestimável para sua organização, você poderá desenvolver novas features, trabalhar em outros projetos ou clientes, movimentar as pessoas entre as equipes, contratar gente nova e inseri-los rapidamente no ‘ritmo’ de trabalho, e o melhor de tudo, o seu cliente manterá a confiança em você, na sua organização e no seu trabalho.

Então, Assim eu termino a discussão: – É mais rápido entregar um produto em 3 meses e levar mais 24 meses ajustando-o para o tornar funcional ou é mais rápido entregá-lo em 4 meses? Ou entregá-lo em 3 meses com menos funcionalidades? – É mais barato arriscar a imagem e confiabilidade da sua organização entregando algo sem qualidade ou é mais barato escrever e automatizar testes?

Xvfb: Como usar o Selenium sem ter um X Server

Escrever testes com Selenium geralmente é uma tarefa que, ou é amada ou é odiada com todas as forças do indivíduo que a executa. Isso acontece principalmente devido às inúmeras formas e ferramentas disponíveis para escrever os seus testes de aceitação. Por exemplo, em Rails quem usa o Cucumber com certeza deve gostar muito de escrever tais testes, já quem usa o Selenium IDE não deve ficar muito feliz depois de algumas semanas repetindo várias e várias coisas.

Executar os testes é outra tarefa muito legal e motivante, ver as coisas acontecendo de forma automática é lindo, mas com o tempo isso começa a ficar muito chato, cansativo e a levar tempo de mais, tempo que você não pode esperar toda vez que quiser fazer um commit ou um push ou até mesmo uma integração para build. Com isso vem a idéia de um servidor de integração contínua onde todos os testes serão executados automaticamente do jeito que você desejar: a cada commit/push, tantas vezes por dia, etc.

Novamente tudo fica muito bom quando o servidor de integração contínua está executando tudo e dando conta do recado, mas e se o servidor disponibilizado não tiver um ambiente gráfico? Ou melhor, e se você questionar a razão de ter um ambiente gráfico num servidor como esse? Bom, há de pensar que sem interface gráfica não é possível executar o browser (exceto o lynx, eu sei), então o que fazer? Para resolver este problema existe o Xvfb, um projeto que serve exatamente para máquinas sem display.

O Xvfb cria um buffer virtual em memória e executa o X Server a partir daí, redirecionando o que deveria ser a saída VGA para a memória, e com isso você consegue um X Server virtual rodando sem display, apenas em memória. Com isso já é possível rodar o browser (e qualquer outra coisa que precisa de um X Server), logo, é possível executar todos os seus testes do Selenium. Um detalhe interessante é a possibilidade de ter qualquer resolução disponível agora, mesmo aquelas que um monitor não poderia te proporcionar.

Vamos agora a instalação e execução do Xvfb:

Instalando o Xvfb

jeveaux@valakas ~ $ sudo apt-get install xvfb

Executando o Xvfb

jeveaux@valakas ~ $ Xvfb :1 -screen 0 1600x1200x32

Com o comando acima vamos iniciar um novo servidor X (:1), screen 0 (-screen 0), resolução de tela de 1600×1200 e 32bits de cores. Agora para abrir o firefox neste servidor:

jeveaux@valakas ~ $ DISPLAY=:1 firefox

E se você quiser acessar visualmente a saída criada pelo Xvfb pode usar algum cliente VNC como o x11vnc e conectar-se no display criado:

jeveaux@valakas ~ $ sudo apt-get install x11vnc
jeveaux@valakas ~ $ x11vnc -display :1

E pronto! Obviamente o Xvfb não deve ser usado exclusivamente para o Firefox/Selenium, este post foi apenas uma abordagem dentre as milhares de soluções que podem se beneficiar de um X Server virtual.

Palestra no CEJUG – Café com Tapioca

Este mês vou tomar café com tapioca lá em Fortaleza, capital do Ceará junto com o pessoal do CEJUG. Dando seqüência ao grandioso trabalho de eventos mensais que o CEJUG vem realizando, participarei do próximo Café com Tapioca no dia 21/11/2008 com a apresentação sobre testes.

Fiquei muito contente com o convite do meu grande amigo, Rafael Carneiro, JUG Leader do CEJUG e um dos administradores do PortalJava, partirei para o nordeste com muita empolgação, afinal além de não conhecer a região vou conhecer várias figurinhas do dia-a-dia de blogs, twitter, IMs e tudo mais, a expectativa é grande.

A apresentação de Testes desta vez terá uma abordagem com maior foco em TDD e BDD. Ainda estou tentando sintetizar o conteúdo da melhor forma possível, torço para que o pessoal do Ceará goste.

Maiores informações aqui no site do CEJUG.