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?
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.