September 24th, 2007Você automatiza seus testes de aceitação?
Muitas equipes XP não automatizam seus testes de aceitação. Essa é uma afirmação dura, porém muito comum de acontecer. A equipe abraça TDD e testes de unidade automatizados, porém quando chega a hora dos testes de aceitação, a coisa complica. Por que isso acontece? Como melhorar essa situação?
Nesse post, inspirado por uma pergunta na XP@Rio, espero dar algumas dicas para ajudar quem tenha se identificado com minha alfinetada. :-)
O que é Teste de Aceitação?
Em primeiro lugar, é bom deixar claro qual a visão Ágil sobre testes. XP, em particular, pede que sejam escritos dois tipos de testes automatizados:- Testes de Unidade: testes do programador. Geralmente testa um pedaço isolado do código. Quando seguimos TDD, o teste é escrito antes do código e funciona como especificação, te ajudando a pensar no design. Depois de escrito, serve como documentação executável do seu código.
- Testes de Aceitação: testes do cliente. Um teste de aceitação (ou Story Test, ou Customer Test) descreve um cenário (de sucesso ou não) com uma expectativa do cliente em relação à história ou funcionalidade. Como o nome sugere, ele ajuda a equipe a entender quando uma história está completa (aceita).
Um pequeno adendo: apesar de ser importante reconhecer esses dois tipos de teste propostos por XP, existem outros tipos de teste igualmente importantes como: testes funcionais, de interação, de carga, de segurança, etc… Isso varia conforme sua situação particular, mas esse não é o assunto desse post :-)
Algumas desculpas
Como disse no início do post, muitas equipes deixam de automatizar seus testes de aceitação. Existem muitas justificativas para explicar esse fato:- Automatizar testes de aceitação é difícil: Testar um sistema web do ponto de vista do usuário ficou muito mais fácil atualmente com ferramentas como o Selenium ou Watir. Testar uma interface gráfica Swing é um pouco mais chato porém não impossível. Testar um software que gera imagens ou modelos visuais (um CAD como o Archimedes, por exemplo) é bem mais difícil. Testar um sistema embarcado depende do hardware. Testar um jogo depende de um jogador (automatizar o jogador pode não ser tão fácil). E por aí vai… dependendo da sua situação, tenho que concordar que sua tarefa pode não ser tão fácil. Mas qual a graça de programar sem desafios? :-)
- O teste fica muito grande: Para testar um cenário, geralmente é preciso fazer muito setUp. Você vai precisar criar diversos objetos, suas associações e terá que se preocupar em apagá-los depois (para manter a independência entre os testes e entre diferentes execuções do mesmo teste). Isso pode gerar problemas de dependência e você passa a perder mais tempo fazendo setUp e tearDown do que efetivamente escrevendo os testes importantes.
- O teste demora muito: O problema anterior faz com que seu teste demore muito para executar. Muitas vezes você pode depender de um banco de dados ou de outro sistema para testar um cenário de aceitação real. Se utiliza um sistema de Integração Contínua, perceberá rapidamente que seus ciclos de build demoram muito mais.
- O cliente não sabe escrever testes: É muito mais fácil um programador aprender a usar o JUnit ou qualquer framework do que o cliente. É papel da equipe encontrar a melhor forma de comunicação com o cliente. Se o cliente trabalha num banco, tente usar uma planilha ou uma tabela. Se seu sistema é cheio de regras de negócio complicadas, tente explorar os diferentes cenários pensando em exemplos. Infelizmente, não existe uma estratégia universal.
Alguns desses problemas são mais difíceis que outros. Mas de que adianta falar mal e enumerar problemas sem dar idéias de soluções?
Sugestões para melhorar a situação
Um novo papel
Quando falo que a Toyota eliminou o departamento de qualidade e teve ganhos incríveis de produtividade, geralmente recebo olhares espantados e desconfiados, principalmente da equipe de testes. “Você está dizendo que devo ser demitido?”. Calma, não é bem assim. A Toyota não eliminou sua preocupação com qualidade. Pelo contrário, ela valoriza tanto esse aspecto que compartilhou essa responsabilidade com TODOS os envolvidos no processo. Não quero que os testadores sejam mandados embora. Pelo contrário, suas habilidades devem ser espalhadas e aproveitadas por todo o processo de desenvolvimento. Devem trabalhar muito mais próximos e não no final da cadeia. Shigueo Shingo já dizia: “Inspecionar para procurar defeitos é desperdício. Inspecionar para previnir defeitos é essencial”. O papel do testador numa equipe ágil é tão importante quanto o do programador. Ele ajuda a equipe e o cliente a aprimorar suas estratégias de teste (principalmente de aceitação). Eles fazem parte da equipe e também são responsáveis pela entrega! Lembrem-se: a história não está pronta enquanto não estiver testada!Reaproveitando uma estratégia conhecida
Eu citei os maiores benefícios dos testes de unidade e TDD: eles te ajudam antes, durante e depois. Antes, te ajudam a especificar o problema e pensar no design do código. Durante, eles servem como rede de segurança, identificando um bug de regressão assim que ele é inserido e dando suporte à refatoração sem medo. Depois, servem como documentação executável do seu código, auxiliando você a dar manutenção e novos integrantes a entender o que o sistema faz. Esses mesmos benefícios se aplicam aos testes de aceitação! O Kent Beck percebeu essa Auto Semelhança na segunda edição do livro de XP. A prática conhecida como Story Test Driven Development (ou STDD) funciona exatamente como TDD, porém no nível das histórias. Eu comentei sobre essa prática num post anterior da XP2007. O cliente deve colaborar com a equipe para enumerar os cenários de aceitação. Pense em exemplos. Uma pergunta que te ajuda a definir tais cenários é: “Como saberei que terminei essa história?”. Se seu cliente não sabe ou não quer definir os cenários de aceitação, apenas responda: “Pronta!”. Os testes de aceitação te ajudam a saber quando a história está pronta. Se o cliente não define nenhum cenário de aceitação, a história está automaticamente pronta (inclusive testada!!). :-)Ferramentas
Diversas ferramentas e frameworks têm surgido para auxiliar sua vida. Como já disse anteriormente, o Selenium e o Watir podem facilitar sua vida no teste de aplicações web. O FIT, que já comentei algumas vezes aqui, também te ajuda a sair do lado técnico e define uma linguagem de comunicação mais simples com o cliente (através de tabelas de exemplo). O Fitnesse armazena essas tabelas (e outras informações) num wiki. Um framework que atraiu bastante minha atenção ultimamente foi o RBehave. Atualmente ele está sendo incorporado ao RSpec, um framework bem conhecido para BDD em Ruby (e Rails, mais recentemente). O assunto teve até um tutorial na última RailsConf na Europa. Ele te permite escrever cenários de aceitação da história de forma executável. Vale a pena dar uma olhada. Tem a versão Java também: jBehave. Apesar de ter escrito muito, acredito ter apenas arranhado a superfície desse assunto tão interessante e tão amplo. Para um pouco mais de informações, sugiro ouvir o AgilCast #9 e assistir alguns dos nossos AgilVídeos. Também gostaria de saber: O que você programa/desenvolve? Qual sua estratégia para automatização dos testes de aceitação? O que de legal você fez em relação ao assunto? Qual sua maior dificuldade?Related posts:






September 24th, 2007 at 11:17 pm
Olá Danilo,
Na minha equipe estamos pulando a parte dos testes de aceitação. Mas não me sinto muito a vontade com isso. Não consegui encontrar a maneira correta de utilizar o selenium no rails(isso nos fez deixar de lado). O Rspec pode entrar no lugar do selenium para esses testes?
Abraços
September 25th, 2007 at 12:19 am
Fala Danilo,
muito legal seu post. Semana passada fiz pair programming com um desenvolvedor da minha equipe, e comecei a explicar e ele sobre TDD. Ele ja conhecia o JUnit, e tinha implementado uns testes. Mas o teste dele era um teste de integracao, muito fragil, pois assumia que a camada que ele interagia estava disponivel, o que nao eh bom. Introduzi conceitos como mock objects e unit tests (como REALMENTE escreve-los) e percebi que ele se demonstrou bastante resistente em faze-lo, pois segundo ele, nao era necessario, ja que a logica foi feita por ele, e ele sabe que esta correta. Segui explicando a ele que este pensamento nao era certo, citando os motivos porque usamos unit tests. Finalmente ele concordou, mas ainda acho que ele nao esta totalmente confortavel com essa ideia de unit tests. Seu post vem como mais um recurso para mostra-lo, na tentative de faze-lo abracar a ideia e fazer com os outros da minha equipe o que fiz com ele. Valew!
September 25th, 2007 at 1:02 pm
Oi Danilo,
Parabéns pelo post. As pessoas realmente tem bastante dificuldade para entender como se trabalha com quality assurance em projetos ágeis. Elas acabam então mantendo os vícios dos projetos tradicionais, deixando pra testar tudo no final da iteração, o que nos leva aos mesmos problemas de qualidade que já enfrentamos a tanto tempo.
Uma outra idéia interessante é permitir gerar a documentação do sistema à partir dos testes. Isso pode elevar ainda mais sua importância e utilidade. Escrevi recentemente sobre isso: http://www.phidelis.com.br/blogs/alissonvale/2007/09/20/DocumentosExecutaacuteveis.aspx
Att,
Alisson Vale
September 30th, 2007 at 6:28 pm
Vou tentar ser matematicamente preciso:
rbehave + rspec = StoryRunner
mas não tenho certeza disso.
Em java também tem o JDave que tenta imitar rspec (obviamente que o código em java não fica tão elegante e natural quanto em ruby).
October 5th, 2007 at 12:53 pm
Se ainda quiseres:
http://www.4shared.com/file/25736635/61e364e5/dojo.html
agora com os testes… hehehe
October 18th, 2007 at 11:44 pm
@Eduardo Fiorezi
O RSpec não substitui o Selenium pois não é um “driver” do browser por Javascript. Ele está mais pra substituir o Test::Unit do Ruby. O que dá pra fazer é usar o RBehave (dá também pra usar o RSpec, mas prefiro deixar ele pros testes de unidade) para dirigir o selenium, usando a API Ruby do Selenium RC.
@Sérgio
Acho que o StoryRunner é só do RBehave. É a classe que executa seus cenários de cada história e coleta os resultados. O RSpec executa suas especificações com o ExampleRunner (acho que mudou o nome de SpecRunner ou BehaviourRunner recentemente). Valeu pela dica do JDave!!
April 5th, 2008 at 4:11 pm
well done, brother
October 28th, 2008 at 6:44 pm
Olá Danilo.
Estou remoando contra a corrente para implementar plano de testes em minha empresa. A resistência é grande, mas acredito que depois que eu estiver usando, outros vão querer. Já instalei o Selenium RC e o IDE mas não sei como integrar os códigos gerados do IDE para o RC. Alguém poderia me dar uma orientação nisso. Pretendo gerar um tutorial e disponibilizá-lo, pois notei que muita gente ainda não sabe como fazer isso.
Grato.
Ricardo Silveira.