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?

Post to Twitter

June 21st, 2007XP 2007 – Dia 4

Conforme eu havia previsto, hoje teria menos coisas para escrever. Como houve manifestações a favor dos meus relatos, vou tentar compensar esse post mais “magro” com mais fotos. Mas isso não significa que pouca coisa aconteceu. Pelo contrário, muita coisa interessante aconteceu: 2 tutorias excelentes, almoço com a Mary e Agile Café. Pena que está acabando…

Thinking, Refining, and Communicating the Business Perspective with Executable Documents – Rick Mugridge e David Hussman

Pela manhã, decidi participar do tutorial sobre Documentos Executáveis com o David Hussman (Agile Coach) e o Rick Mugridge, co-autor do famoso livro sobre FIT, apesar de ter participado de uma sessão sobre o framework na Agile 2006. O interessante foi que a ênfase da apresentação foi muito além da ferramenta FIT/FitNesse/FitLibrary. O conceito da documentação executável como elemento de comunicação com os clientes e como forma de definir os cenários de aceitação de uma história vai muito além da ferramenta. Documentos Executáveis são aqueles que não são escritos uma vez só; aqueles que não tendem a ser esquecidos ou a crescer infinitamente; aqueles que ajudam as pessoas a pensar e colaborar; aqueles que ajudam as pessoas a comunicar o que o produto realmente faz.

Algo que gostei muito, e que não tinha visto de forma formalizada antes, foi a prática conhecida como Story-Test Driven Development (STDD ou Desenvolvimento Dirigido por Testes de Histórias), onde antes de fazer TDD, a equipe de programadores, analistas, testers e clientes colabora para definir os critérios de aceitação da história antes mesmo de começar a desenvolver. Como a Mary disse no seu tutorial, por que uma equipe de desenvolvedores deve começar a trabalhar numa história sem saber o que deve fazer? Segunda ela, na empresa do Jeff Sutherland (criador do Scrum e CTO da PatientKeeper) os desenvolvedores não podem colocar a mão numa história se ela não é “testável”. Se o cliente não consegue (ou não se importa em) sentar com a equipe para definir exatamente o que espera do software desenvolvido, não tem sentido começar a programar. Qual o valor esperado?

David Hussman apresentando STDD

Segundo os palestrantes, o caminho para chegar a uma documentação executável passa por diversas etapas:

  • Personas: Para quem não conhece, é uma prática criada por Alan Cooper para descrever os usuários do sistema de forma mais humana. Ao invés de usar “homens-palito” (ou seja lá como chamam esses bonequinhos), uma persona tem nome, foto (ou caricatura), interesses pessoais e valores que espera extrair do produto. No artigo que vou apresentar semana que vem na WDRA (em Porto de Galinhas!), apresento de forma breve essa prática que é muito eficiente (e divertida).
  • Histórias: Partindo das personas, você consegue enxergar diversos objetivos e tarefas que um usuário irá realizar no seu sistema. Fica bem mais fácil escrever histórias a partir dessas tarefas.
  • Testes de Histórias (Story-Tests): Uma vez que temos histórias, é hora de colaborar com o cliente para entender o que eles realmente querem. Dessa conversa devem surgir os testes de histórias (ou testes de aceitação, como o Kent Beck definiu em XP).
  • Cenários, tabelas/fixtures (no caso do FIT), APIs, etc: No momento que a equipe entende a real necessidade do cliente (que pode mudar com o tempo, mas isso é normal), precisam garantir que aquilo seja armazenado de forma executável e que sirva como ferramenta para informar o desenvolvedor quando uma história está quase pronta (“quase” pois o seu conceito de “pronta” pode – e deve – ir mais além da codificação/teste).
  • Documentos Executáveis: Só depois de tudo isso você é capaz de construir uma documentação executável. Essa documentação serve como registro de como o sistema deve funcionar e, quando o cliente mudar de idéia ou quiser discutir algo em particular, ela pode ser alterada/testada em ciclos curtos de feedback para garantir que o sistema se adapta às novas necessidades.

Personas

No final, o grupo se dividiu e a discussão continuou entre os mais interessados no nível mais técnico (discutindo o FIT/FitNesse em particular) e os mais interessados no nível mais amplo. Fiquei um pouco em cada discussão.

From User Story to User Interface – Jeff Patton

Na parte da tarde participei de mais um excelente tutorial com o Jeff Patton, da Thoughtworks. Material impecável, slides e timing muito bons, didática excelente e exercícios práticos divertidos e instrutivos. E, claro, um assunto muito interessante: como o design de usabilidade (por aqui mais conhecidos como Interaction Design) e o design de interfaces gráficas se encaixam no mundo ágil?

Quem vive no mundo do design de interfaces e da usabilidade tem uma propensão a trabalhar com BDUF (Big Design Up-Front). O que geralmente se diz é que você precisa ter uma idéia de todas as possíveis formas de interação e atividades que um (ou vários) usuário(s) terão com o sistema antes de projetar a melhor interface e o melhor design gráfco. Nós do mundo ágil sabemos que BDUF não funciona muito bem. Num dos relatos de experiência apresentados anteriormente, Robert Beedle mostrou um estudo empírico qualitativo mostrando que, em geral, a maioria das atividades de definição de interface tendem a acontecer no início dos projetos mesmo. Ele mostrou quatro abordagens diferentes:

  • Fazer todas as atividades de design da interface antes de começar a desenvolver
  • Fazer ambas as atividades em paralelo, de forma iterativa
  • Fazer ambas as atividades em paralelo, porém trabalhando no design de interface uma iteração na frente (de forma que a equipe de desenvolvimento trabalha sempre em cima do que a equipe de interface desenvolveu na iteração anterior)
  • Começar somente com atividades de design da interface e, gradualmente, inserir atividades de desenvolvimento. Conforme as iterações vão passando, a quantidade de trabalho de desenvolvimento vai aumentando enquanto de design diminui, até o momento em que só é preciso desenvolver. Algo como aqueles gráficos de baleia do RUP.

No tutorial, Jeff apresentou o modelo em camadas proposto por James Garrett para descrever os diferentes elementos da Experiência do Usuário:

  • Superfície: interface gráfica, com cores e elementos gráficos do design.
  • Esqueleto: uma espécie de “wireframe” de como os elementos estão estruturados na interface.
  • Estrutura: como os elementos da interface estão conectados para formar um todo.
  • Escopo: uma lista de tarefas que um usuário tipicamente irá realizar através da interface.
  • Estratégia: os objetivos por trás das tarefas que serão realizadas na interface.

Apresentou também as diferentes formas de representar os usuários (Atores, Papel, Perfil ou Persona) e as diferentes formas de capturar e representar as interações do usuário com o sistema, como: Use cases, Histórias, Workflows, Cenários e Modelo de Tarefas. Durante o resto do tutorial, nos organizamos em grupos e realizamos diversas atividades para produzir e validar um protótipo em papel: partimos de uma história e definimos um simples cenário de uso, descrevendo as interações entre o usuário e o sistema (num formato de Use case essencial). A partir disso, definimos os diversos componentes que fariam parte da interface gráfica para que o cenário fosse atendido.

Componentes da interface gráfica em fase de incepção

Depois veio a parte divertida: começamos a desenhar e recortar os diversos componentes e “montar” a interface em papel, usando canetinhas, papel, transparências, cola pritt e liquid paper.

Criando nosso protótipo em papel

Por fim, vimos como funciona um teste de usabilidade num protótipo de papel e como, depois de poucas iterações, conseguimos diminuir o número de erros de usabilidade. Para isso, cada um tinha um papel (role, para não confundir): o “facilitador” apresentava nossa proposta e era o único que podia conversar com o usuário-final (num estilo narrador de esporte). Outra pessoa faz o papel de “computador” e fica trocando os papéis/botões/transparências conforme o usuário-final interage com o protótipo. Além do “usuário-final” (que eram duas pessoas vindas de uma outra equipe), alguém precisa fazer o papel de “observador” e ficar tomando nota dos problemas encontrados durante o teste.

Teste de usabilidade do protótipo com usuários de outra equipe

Foi uma experiência valiosíssima (o melhor tutorial até agora na conferência) e aprendi bastante sobre como integrar o mundo do design com o mundo de desenvolvimento. Nós sempre aprendemos bastante quando passamos por problemas parecidos. O Jeff está fazendo um trabalho excelente para juntar essas duas comunidades. Para quem se interessar, vale a pena conferir as suas idéias.

Discussões em Geral

Não bastassem os ótimos tutoriais, aind tive o privilégio de ser convidado para almoçar com a Mary e com o Tom para discutir várias coisas. Uma das discussões foi a respeito da velocidade, e expressei minha opinião (e a da Mary) na XP@Rio. Não vou me repetir por aqui. Se alguém se interessar, é só seguir o link. :-)

Como comentei, as pessoas que não estão participando de workshops ou tutoriais geralmente se reúnem nas mesas de fora do hotel para discutir assuntos ágeis, no que foi batizado como Agile Café. Dei uma passada no final do dia, mas já estava cansado e resolvi voltar pro hotel para descansar. Por hoje é só, pessoal. Amanhã é dia de mais um tutorial e um workshop. Arrivederci!

Post to Twitter


© 2007-2009 Danilo Sato | Powered by Wordpress

Page optimized by WP Minify WordPress Plugin