Archive for the ‘TDD’ Category

usando o webdriver para fazer testes de aceitação

janeiro 27th, 2010

A pouco tempo consegui um brecha com ajuda da minha colega Arlene para implantarmos no projeto que estou trabalhando teste automatizados.  Com a carta de alforria em mãos partimos para pesquisar no mercado qual seria a melhor que se encaixaria em nosso contexto de aplicação.  Para que entenda,  trabalhamos com desenvolvimento de portal usando a ferramenta Lumis (eu trabalho na Lumis!!!).  Portais são aplicações bastante difíceis de serem testadas de forma automática; devido a questão do conteúdo dinâmico e pouco previsível não existe muita margem para que busque por padrões.

Com estas limitações em mãos, acabamos nos deparando com a api WebDriver . A um tempo atrás eu já tinha mexido um pouco com o selenium e adorei. Com isso, tentei achar algo que se assemelhasse a ele mas que me facilitasse a vida em relação a portais ( não tem muito como usar ids dos elementos no html, url não fixas, etc) . O webdriver, ao contrário do selenium, não é um javascript que executa dentro de uma página simulando a navegação… o webdriver é realmente um “envelope” em cima do seu navegador.  No caso do Firefox ele é uma extensão, no caso do Internet Explorer (blargh) ele usa as chamadas de control que ele proporciona, e por ai vai. Com isso, os teste ficam mais próximos da realidade de uso do usuário, e a api para escrever  os cenários mais simples.  Veja o trecho:

1
2
3
4
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/");
HomePage homePage = new HomePage(webDriver);
String valor = homePage.searchFirstItemforMoreRead();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class HomePage  extends Page {
private static final String PAGE_TITLE = "teste";

public HomePage(WebDriver driver){
super(driver,PAGE_TITLE);
}

public AdminPage navegateToAdministration(){
webDriver.navigate().to(this.composeUrl("admin"));
return new AdminPage(webDriver);
}

public String searchOneTextOfDestaque3(){
return this.webDriver.findElement(By.xpath("//div[@class='destaques3']/h5/a")).getText();
}

public String searchFirstItemforMoreRead(){
return this.webDriver.findElement(By.xpath("//div[@class='aba_conteudo ativo']/ol[@class='mais_lidas']/li[@class='item1']/a/span")).getText();
}

public List searchDestaque3Texts(){
return this.webDriver.findElements(By.xpath("//div[@class='destaques3']/h5/a"));
}

}

Pelo exemplo acima fica fácil de ver o quão fácil é criar um teste em webdriver.  Recomendo experimentar

O bom, o feio e o mal em desenvolvimento – parte 1 – testes automatizados

janeiro 11th, 2010
Conversando com um colega do trabalho, discutíamos sobre a questão dos testes automatizados. Confesso, que nessa altura dos acontecimentos de TI, esse assunto estaria mais que esgotado, porém para minha surpresa, existe gente que ainda insiste dizer que é “perda de tempo” e outros termos menos lisonjeiros.
Esse colega me contou de um projeto onde existiam diversos problemas e que o cliente estava bastante insastifeito, entre outras coisas, com a qualidade das entregas. Isso porque, segundo o próprio cliente, várias vezes as alterações feitas ocasionavame na quebra de funcionamento em outras partes que aparentemente não tinham relação com a mudança pedida.
Quem um dia já trabalho com portais, por exemplo, sabe a encrenca que isso é: páginas, conteúdo dinâmico, caches primários e secundários, gestão de conteúdo instâncias de serviços, etc. Com isso, o entrelaçamento das coisas  é enorme e qualquer alteração implica, considerando situação ideal, no teste de todo o portal. Testar o portal inteiro significa, para uma pessoa, horas e até dias de trabalho (se considerarmos portais de notícias como o G1 e o R7). Agora imagina testar todo o portal a cada commit que for feito… impossível né! não quando automatizamos nossos testes ao invés de delegar isso para uma pessoa.
Antes que comecem o apedrejamento em praça pública de minha pessoa, não estou dizendo para demitir toda a sua equipe de testes (os famosos homologadores). Estou dizendo que as coisas podem ser feitas com um pouco mais de inteligência e maior valor agregado para o cliente.
Voltando a história do meu amigo, devido a questões de negócio, optaram por não “gastar” tempo em criar testes automatizados e o cliente se prontificou em testar tudo que era feito através de sua equipe interna de testadores profissionais. Nem preciso dizer que esta é a raiz da insatisfação do cliente com o quesito qualidade do projeto. Fazendo uso de um ditado popular : “Cão com muito dono ou nenhum, morre de fome de sede” .
Nessa história, quem tomava a decisão estava com uma visão antiga e com prazo de validade vencido sobre a questão de testes. Eles realmente acreditaram ( e acreditam – daqui a pouco chego lá) que investir em automatizar testes é custo e não investimento.  Esqueceram de considerar a qualidade… pensaram somente que precisavam colocar no ar o mais rápido o possível o sistema e os “fins justificariam os meios empregados”. Eles já estão pagando o preço pela péssima escolha, mas como todo “cego opcional” eles, pasmem vocês, não querem que “percamos” tempo em fazer esses bobeiras e culpam os desenvolvedores de todos os erros chamando-nos de incompetentes.
A minha resposta para este conhecido foi simples: mude de emprego. Faltou alguém de visão no projeto para entender que teste nunca é demais. Testes automatizados são um ganho e não perda de tempo. Vejam que nem estou falando em TDD, estou apenas considerando os testes !!!!
Quando “cercamos” nossas as aplicações testes, no mínimo estamos tentando protejar a consistencia da aplicação, evitando que mudanças quebrem-na. Claro que esse testes poderiam ser feitos por uma pessoa, mas imagine o custo (dinheiro mesmo !!!! tempo!!!) para que isso fosse feito num tempo hábil e com um retorno rápido para o desenvolvedor… Teste automatizados garantem isso. Sua aplicação pode ser testado o tempo todo e com isso, mesmo pequenas alterações levam a testar o todo verificando se a integridade não foi quebrada.
Isso, apesar de no começo representar mais trabalho, no final, gera um valor agregado imenso pois as coisas são entregues quando realmente estão prontas e com uma qualidade minima. Caso ainda queiram passar pela equipe de homologação, essa ficará livre para testar os requisitos e não se campo numérico aceita string.
Na literatura corrente, e por isso não foi me extender mais, existem diversos livros, artigos, blogs, textos, twitter, etc mostrando e provando porque devemos usar testes automatizados. Porém, me assusta o fato de ainda existirem gerentes, diretores e donos de empresa que consideram isso perda de tempo. Para estes a previsão é sombria. O mercado está aquecido por isso qualquer “bundão” consegue vender algo. Haverá um momento de retração e nova expansão e aí, somente quem estiver pronto, ágil e preparado sobreviverá… e não acredito que esses caras que eu citei estarão preparados.
Bem isso, até a próxima.

Documentar é preciso e faz bem

setembro 26th, 2009

Esses dias li um e-mail numa lista de discussão que participo onde a pessoa perguntava como ela deveria fazer para documentar um projeto que ele desenvolveu sozinho. Ainda segundo ele, a ideia é de permitir que num futuro próximo um novo desenvolvedor possa trabalhar no sistema sem traumas e com uma curva de aprendizado rápida.

Antes de tentar responder a pergunta, acredito seja necessário entender a diferença entre análise e documentação.  Muitas pessoas que trabalham com  criação de softwares, acabam confundindo documentar com analisar.  Essa dúvida é normal pois muitas “ferramentas” e “métodos” também se apresentam como opção de documentação, ou o contrário : coisas que deveriam ser usadas para documentar são usadas para fazer análise ( e até acabam com uma má fama sem terem culpa disso – puro mal uso). Um exemplo disso, no meu ponto de vista, é o uml : Muitos usam a UML com o propósito de analisar e modelar. Ela até foi criada com esse intuito pois, quando foi concebida  era bastante custoso codificar e alterar o código feito (lembre-se dos cartões perfurados, cobols da vida, etc) mas hoje isso já não é válido (com linguagens modernas, codificar é rápido e alterá-lo mais ainda). Voltando, UML, no meu ponto de vista, é muito mais documentativa do que modelagem.  Seus diagramas tem um ótimo apelo de representar graficamente um sistema e como diz um ditado: “Uma imagem vale por mil palavras”.

Um outro mito a ser desfeito, insisto, no meu ponto de vista, é de que documentar não agrega valor. Por mais que ninguém diga isso, por mais que ninguém escreva isso, por mais que ninguém assuma isso, muitos de nós considera o ato de documentar como uma atividade secundária, e com isso, delegamos para que outros façam ou, em piores casos, nem o fazemos. A questão que ninguém escreve um sistema para si e, na maioria dos casos, não fazemos isso sozinhos.  Outro ponto é que, possivelmente, não ficaremos para o resto de nossa vidas com aquele projeto, passaremos para outros desafios e aquele sistema deverá ser cuidado por outro pessoa que não necessariamente participou da equipe que o desenvolveu. Tal fato, implica em ter que forma esse pessoa de forma que ela possa dar continuidade ao aplicativo sem comprometer a qualidade dele (estou assumindo que seja aqueles projetos onde temos testes automatizados, linguagens bem expressivas, etc). Logo, tendo todo esse contexto em mente, fica fácil mostrar que documentar, no mínimo, é evitar dores de cabeça futuras.

Mas, enfim, como documentar?

A pergunta poderia ser redigida da seguinte forma para ter mais sentido para nós : Como podemos documentar sem que isso seja uma atividade secundária e agregue mais valor ao sistema? .  A maioria das linguagens modernas oferecem recursos, bastante interessantes, que podem responder essas perguntas. Em Java, nós temos o recurso básico do JavaDoc (comentários em formato especiais que são colocados no código fonte. Depois, através de ferramenta exportamos para um html), em .NET (csharp) temos algo parecido, e por ai segue. Embora isso já seja algo que ajude, considero insuficiente como documentação pois, quem irá ler não terá uma visão do funcionamento ou do comportamento do sistema.

Nesse contexto de comportamento e funcionamento que entram a ajuda primordial dos teste automatizados. Um efeito secundário dos testes automatizados (tanto os teste unitários quando os testes de comportamento) é de, se bem escritos e de grande abrangência,  eles acabam sendo uma boa fonte de consulta para o entendimento da aplicação.  Existe, inclusive, frameworks de teste de comportamento (Behavior Tests) que permitem que se escrevam de forma literal facilitando ainda mais o seu uso como documentação, como por exemplo o Cucumber (Ruby), Pyccuracy ( espero ter escrito certo – Python), etc.

Por fim, eu pessoalmente, acredito que um bom diário de bordo também ajuda bastante. Um diário de bordo, consiste, em algo parecido com um blog ( pode até ser um blog), em que vou escrevendo o dia a dia do desenvolvimento tentando retratar as decisões não técnicas e situações vencidas pela equipe de forma que a pessoa que irá trabalhar com o sistema no futuro tenha também uma visão do por que de certas escolhas, do sentimento da equipe naquele momento, etc.

TDD- desenvolvimento guiado por testes

junho 2nd, 2009

Uma coisa que sempre considerei interessante é a resistência de alguns de não partir para uma forma de desenvolvimento guiado por testes. Eu, assim que tive contato com este jeito de programar, nunca mais larguei e hoje, confesso, nem consigo fazer de outra forma.Ao me guiar por testes meu códigos sempre saem com qualidade acima da média (melhor que a da maioria no mercado). Este resultado se deve, não por minha suposta genialidade mas sim, por sempre testar de forma minunciosa as coisas (testes unitários, testes de comportamento, etc), escrever testes antes, etc.
Estamos sempre em busca de fazer mais em menos tempo… essa tem sido a missão principal de todos nós seres humanos e claro que não é diferente para desenvolvimento de sistemas. A pressão de prazos, custos, etc são aspectos importantes nos projetos e tem nos levado a buscar alternativas para atender. Por vezes, a opção acaba sendo, fazer sistemas de forma amadora, cheios de “gambiarras” e remendos, tudo para que o sistema seja entregue no dia e lucro desejado. Isso faz sentido, e é interessante, apenas para aquelas consultorias que ganham “rios de dinheiro”, pois além do desenvolvimento, elas aproveitam para vender, também o suporte. Mas para aqueles que desejam entregar coisas com qualidade, para os clientes que precisam de sistemas que realmente apresentem um ROI (retorno de investimento) sastifatório, uma solução tem sido o desenvolvimento guiado por testes, TDD.
Realizar um desenvolvimento guiado por teste significa, sendo bastante simplista, escrever os testes de acordo com a especificação do sistemas e estes determinarem a forma que o sistema serà implementado pois o código para ser aprovado deve passar pelos teste criados. Complicou, a gente descomplica: ao invés de desenvolvermos um sistema e depois testá-lo, verificando se ele funciona, se trata todos os casos, se ele é robusto, tolerante a falhas ,etc; nós escrevemos diversos testes automatizados(unitários, comportamento, etc) e vamos desenvolvendo o sistema de forma a que todos os testes sejam aprovados. Ao inverte a forma de conceber as coisas, um senso comum entre os autores que falam sobre TI, os ganhos são significativos ao ponto de não podermos ignorá-los:
1 – Evita-se desperdício de código: implementa-se o necessário para que teste funcione.
2 – Cobertura total contra falhas: Ao escrever os testes antes evita-se a programação otimista, ou seja, o programador não tem tentação de escrever e testar apenas o “caminho feliz”; escreve-se os testes de acordo com a especificação.
3 – Testes automatizados : sei que muitos poderiam dizer que teste automatizados não um ganho particular do TDD, mas são sua pedra fundamental. Ao automatizar seus testes, a cada nova compilação ou ação sobre o código, todo o sistema será testado garantindo seu funcionamento. Isso, gera uma robustez na solução pois evita que os efeitos colaterais desconhecidos, ao alterar uma aplicação, apareçam somente em produção.
Um gerente mais apegado ao passado poderia dizer que escrever testes antes significa perder tempo, pois ele vai precisar de prever mais dias em seus cronograma para a entrega do sistema. Isso, de certa forma, está correto. Entretanto, o material entregue é de grande qualidade pois foi amplamente testado, retestado, e por aí segue… não teremos retrabalho, horas extras para corrigir bugs desconhecidos, cobertura total para alterações…
Sei que isso não é a “bala de prata”: o fato de usar desenvolvimento guiado por teste, não garante que seu aplicativo será o melhor, ainda existe o talento da equipe, a tecnologia, uma boa especificação, etc. Embora, o uso de TDD em minha opnião, já seja 60% do caminho para tal objetivo.
Na próxima vez que for começar a desenvolver, pense nisso… Permita-se experimentar e espero, que assim como eu, vocês fiquem viciados nessa prática.