Gerência - Qualidade e Testes

Testes Extremos - Entenda o papel do testador em projetos ágeis

O XP (Extreme Programming) é um processo simples e ágil baseado no contato direto com o cliente. Os requerimentos são capturados em estórias (User Stories) e o software é desenvolvido em pequenas iterações onde essas estórias são escalonadas.

por Cristiano Caetano



O papel do testador em projetos ágeis

O XP (Extreme Programming) é um processo simples e ágil baseado no contato direto com o cliente. Os requerimentos são capturados em estórias (User Stories) e o software é desenvolvido em pequenas iterações onde essas estórias são escalonadas. O código é escrito seguindo padrões previamente definidos e pode ser escrito por pares de programadores. Adicionalmente, utiliza-se o desenvolvimento dirigido a testes (por meio da criação de testes unitários antes de iniciar a escrever o código), criando assim um ambiente perfeito para otimização e eliminação de duplicações por meio da refatoração (Refactoring). A partir dessa perspectiva, percebe-se que o Extreme Programming propõe uma infra-estrutura onde o software é desenvolvido em pedacinhos, mas, no entanto, cada pedacinho é submetido a todas as fases do ciclo de vida do software, da concepção ao teste. Nessa estratégia, cada pedacinho construído numa iteração é testado (por testes unitários ou testes de aceitação), viabilizando assim, a identificação e correção dos erros de concepção ou programação (e poupando muito tempo e dinheiro, afinal, quanto mais tarde um erro for detectado, maior será o custo e o tempo para corrígi-lo, como pode ser visto na Figura 1).


Figura 1. Custo médio da correção de um defeito ao longo do ciclo de vida de desenvolvimento de um software.

Apesar de muitos livros e alguns puristas defenderem que os projetos baseados em Extreme Programming não precisam de testadores em virtude de que o código é 100% coberto por testes unitários, os fatos dizem o contrário. Por maior que seja a cobertura dos testes de unidade, é impossível prever o comportamento do software quando integrado e funcionando no ambiente de produção. Os testes unitários normalmente são executados num ambiente estável contra uma configuração de teste limitada e bem definida. Em outras palavras, raramente os testes unitários são executados, por exemplo, em todos os sistemas operacionais e banco de dados suportados pelo seu software. Qualquer deslize de programação poderá criar um cenário onde uma funcionalidade funcione perfeitamente no Windows, mas por outro lado, não funcione corretamente no Mac OS X. Robert Glass, no seu famoso livro "Facts and Fallacies of Software Engineering" [1] afirma: "Fato 32 - Pesquisas indicam que quando um programador diz que o código foi completamente testado, normalmente isto significa que apenas cerca de 55% a 60% dos caminhos lógicos do código foram realmente testados. Isso demonstra quão pouco o desenvolvedor entende acerca do código que ele mesmo criou". Não se trata de um problema do programador ou do papel que ele desempenha no projeto, mas um problema de percepção e entendimento. No artigo "Processos e qualidade de software" [2] eu descrevo um exemplo que demonstra a natureza ambígua da percepção humana por meio da ênfase de diferentes palavras em uma frase. A mensagem transmitida pela frase analisada na Figura 2 pode ter um significado totalmente novo conforme as diferentes interpretações da palavra enfatizada.


Figura 2. Podemos obter diferentes percepções enfatizando diferentes palavras de um requisito.

Atividades desempenhadas pelo testador

Como pode ser observado na Figura 1, apesar do custo médio de correção de um defeito ser extremamente baixo quando encontrado em fases iniciais do ciclo de vida de desenvolvimento de um software, podemos notar que os testes de unidade detectam na média apenas 20% dos defeitos de um software. Por outro lado, os testes desempenhados pelos testadores (testes de integração e de sistema) detectam cerca a 40% dos defeitos de um software (sem contar os demais testes que os testadores normalmente estão envolvidos). Em resumo, no artigo "XP Testing Without XP: Taking Advantage of Agile Testing Practices"[3], Lisa Crispin elenca as principais atividades desempenhadas por um testador num projeto ágil:

  • Negociar qual o nível de qualidade esperado pelo cliente (não o seu padrão de qualidade, mas o padrão que cliente desejar e estiver disposto a pagar);
  • Clarificar estórias e esclarecer suposições;
  • Prover estimativas para as atividades de desenvolvimento e testes;
  • Garantir que os testes de aceitação verificam se o software foi construído conforme o nível de qualidade definido pelo cliente;
  • Ajudar o time a automatizar os testes;
  • Ajudar o time a desenvolver código testável;
  • Prover feedback contínuo para manter o projeto no rumo.
Testes de aceitação

Durante a fase de planejamento são definidas as estórias e os testes de aceitação da iteração. Os puristas afirmam que estas atividades devem ser realizadas pelos programadores e pelos clientes. No entanto, tanto os programadores quanto os clientes não são capacitados tecnicamente para elaborar testes de aceitação refinados. Testadores experientes são essenciais para a criação de testes de aceitação eficazes, tanto no ponto de vista funcional quanto do não-funcional, como por exemplo, testes de carga, performance, usabilidade e assim por diante. Não se trata de menosprezar os papéis dos programadores e dos clientes em projetos ágeis, mas uma questão de realizar as atividades com os recursos certos, afinal, testadores com experiência nas técnicas de testes estruturais e funcionais podem agregar muito valor na definição dos testes de aceitação. Além disso, os testadores têm a função de estabelecer uma linguagem comum entre os membros do time, estimulando o intercâmbio de conhecimento e, conseqüentemente, garantindo o nível de qualidade esperado pelo cliente.

Redundância

Testadores em projetos ágeis são redundantes. Sim, isso mesmo! Testadores são como os airbags dos automóveis. Apesar dos cintos de segurança serem eficientes na prevenção de acidentes, os airbags oferecem uma proteção a mais; ou uma proteção para os tipos de acidentes em que os cintos de segurança são pouco eficientes. Se aplicarmos essa metáfora no dia-a-dia dos projetos ágeis, veremos que projetos baseados em Extreme Programming utilizam diversas práticas redundantes para eliminar ou reduzir a quantidade de defeitos da aplicação. Programação em pares, requisitos testáveis, integração contínua, testes de unidade, testes de aceitação, entre outros, são práticas redundantes que tentam reduzir a ambigüidade dos requisitos ou a quantidade de defeitos da aplicação. Kent Beck, no seu livro "Extreme Programming Explained Embrace Change" [5] afirma: "Você não pode resolver os defeitos com apenas uma prática. Os defeitos são muito complexos e cheios de facetas e nunca serão resolvidos completamente. (...) Algumas práticas são certamente redundantes, identificando os mesmo tipos de defeitos. Apesar dessas redundâncias serem um desperdício, seja cauteloso ao remover práticas redundantes que sirvam para alguma proposta. (...) O preço da redundância é mais do que pago pela economia de evitar a ocorrência de um desastre".

Integração Contínua

Kent Beck, no seu livro "Extreme Programming Explained Embrace Change" [5] afirma: "Desenvolvimento em time não é um típico problema de dividir para conquistar. É um problema de dividir, conquistar e integrar. A etapa de integração é um passo imprevisível e pode facilmente levar mais tempo do que o desenvolvimento dos módulos que estão sendo integrados. Quanto mais tempo você esperar para integrar, mais caro e imprevisível será o custo da integração". A Integração Contínua tem a função de estabelecer um ambiente de integração sistemático, criando um ciclo virtuoso onde os defeitos são detectados e corrigidos precocemente. Em resumo, a proposta da Integração Contínua é a criação de um ambiente separado e independente do ambiente de desenvolvimento, onde as modificações individuais são unificadas freqüentemente, a aplicação é compilada, os testes unitários e os testes de aceitação são rodados, a documentação é gerada e assim por diante, como pode ser visto na Figura 3. Neste cenário, os testadores realizam um papel fundamental auxiliando os programadores a identificar e solucionar os problemas de integração, assim como, na instalação e manutenção do servidor de integração contínua. No entanto, cabe ressaltar que testadores convencionais normalmente não têm conhecimento na instalação e configuração de tais tipos de ferramentas de Integração Contínua. Sendo assim, convêm que os testadores tentem aprender e aplicar técnicas e ferramentas que não fazem parte do seu dia-a-dia ou do escopo do seu trabalho. No artigo "Os 7 hábitos dos Testadores Altamente Eficazes" [9], eu afirmo "(...) para se tornar um mestre no seu ofício, é necessário ampliar os seus conhecimentos, aprimorar as suas habilidades e manter sempre inflamado o desejo de tornar-se um profissional melhor dia após dia. (...) para tornar-se mestre na arte de testar software, você deve ser inovador e reinventar o seu trabalho todos os dias"


Figura 3. Integração Contínua.

Automação de testes

Segundo Cem Kaner, autor do livro "Lessons Learned in Software Testing" [4], o propósito da automação de testes pode ser resumidamente descrito como a aplicação de estratégias e ferramentas tendo em vista a redução do envolvimento humano em atividades manuais repetitivas. Kent Beck, no seu livro "Extreme Programming Explained Embrace Change" [5] acrescenta: "Identifique o defeito no momento que ele é criado e o custo para corrigir será mínimo", como pode ser visto na Figura 4.


Figura 4. Freqüência dos testes automatizados. Os testadores podem desempenhar um papel fundamental nos projetos ágeis por meio da automação dos testes de aceitação. Somente por meio da automação dos testes de aceitação, os testadores podem reduzir o seu envolvimento em atividades manuais repetitivas (sobrando assim mais tempo para realizar as outras atividades que discutimos ao longo deste artigo) e, por sua vez, executar os testes freqüentemente (idealmente dentro de um processo de Integração Contínua). No artigo "Top 10 Testing Mistakes XP Teams Tend to Make" [6], Elisabeth Hendrickson destaca que muitos projetos ágeis estão deixando de automatizar os testes de aceitação em função do tempo que essa atividade consome e da sua complexidade. No entanto, se o teste for difícil de automatizar isto significa que o aplicativo deveria ser reprojetado para tornar o teste mais fácil. Afinal se é difícil de testar, provavelmente ninguém irá testar e, por conseqüência, muitos defeitos críticos poderão ser ignorados. Por outro lado, os testadores têm se beneficiado da evolução das ferramentas de testes automatizados. Ferramentas open source tais como Selenium, Watir ou FitNesse representam uma quebra de paradigma em relação as ferramentas de automação tradicionais que são baseadas em Record/Playback e geram como resultado scripts confusos em algum tipo de sublinguagem de programação (variações limitadas de Visual Basic, Java ou linguagem proprietárias). Esta nova geração de ferramentas automatizadas se baseiam em palavras-chave (Keywords) que representam as ações dos usuários e são, por sua vez, encadeadas em tabelas HTML ou em Wikis, como pode ser visto no exemplo apresentado na Figura 5. Seja qual for a forma de expressar as ações automatizadas e os casos de testes, a premissa básica destas ferramentas é promover a criação de casos de testes automatizados com comandos de alto nível e que podem ser entendidos pelos clientes (ou até mesmo escrito por eles).


Figura 5. Exemplo de teste de aceitação automatizado criado com o Selenium.

Testes Exploratórios

O teste exploratório é, na sua definição mais básica, a criação e a execução ao mesmo tempo de um teste [7]. Quando se realiza um teste exploratório, normalmente o testador não tem informações detalhadas sobre o que vai testar e como vai testar. O testador se baseia na sua experiência, assim como no conhecimento que ele vai adquirindo sobre o aplicativo durante a execução do teste exploratório. A partir dessa perspectiva, podemos afirmar que o teste exploratório é uma atividade iterativa e empírica de exploração que exige idas e vindas num processo de investigação contínuo onde a intuição, a criatividade e a experiência do testador são indispensáveis para garantir a eficiência do teste. Nos testes exploratórios, não existe uma forte dependência entre os testes e os requisitos, assim como, não é necessário um planejamento prévio muito detalhado sobre quais testes serão executados; o que torna o teste exploratório uma ótima escolha para a realização de testes quando não existe um conhecimento prévio sobre o aplicativo que será testado ou em metodologias ágeis (como o Extreme Programming) onde não existem documentos de requisitos formais, como pode ser visto na estória exemplo (User Story) apresentada na Figura 6. Jonathan Kohl, no seu artigo "Exploratory Testing on Agile Teams" [8] acrescenta: "Interfaces de usuários são notoriamente difíceis de testar, e testadores exploratórios têm um bocado de experiência para lidar com elas".


Figura 6. Exemplo estória retirado do site http://www.agilemodeling.com

Links

[1] Facts and Fallacies of Software Engineering By Robert L. Glass
http://www.amazon.com/Facts-Fallacies-Software-Engineering-Robert/dp/0321117425

[2] Processos e qualidade de software
http://www.linhadecodigo.com.br/artigos.asp?id_ac=964

[3] XP Testing Without XP: Taking Advantage of Agile Testing Practices
http://www.methodsandtools.com/archive/archive.php?id=2

[4] Lessons Learned in Software Testing
http://www.amazon.com/Lessons-Learned-in-Software-Testing/dp/0471081124

[5] Extreme Programming Explained Embrace Change
http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0201616416

[6] Top 10 Testing Mistakes XP Teams Tend to Make
http://www.testobsessed.com/2006/03/23/top-10-testing-mistakes-xp-teams-tend-to-make/

[7] Testes Exploratórios de A a Z
http://www.linhadecodigo.com.br/artigos.asp?id_ac=1102

[8] Exploratory Testing on Agile Teams
http://www.informit.com/articles/article.asp?p=405514&rl=1

[9] Os 7 hábitos dos Testadores Altamente Eficazes
http://www.linhadecodigo.com.br/artigos.asp?id_ac=1083

[10] Testes de aceitação
http://en.wikipedia.org/wiki/Acceptance_test

[11] FitNesse
http://fitnesse.org/

[12] Watir
http://www.openqa.org/watir/

[13] Selenium
http://www.openqa.org/selenium/

Cristiano Caetano

Cristiano Caetano - É certificado CBTS pela ALATS. Consultor de teste de software sênior com mais de 10 anos de experiência, já trabalhou na área de qualidade e teste de software para grandes empresas como Zero G, DELL e HP Invent. É colunista na área de Teste e Qualidade de software do site linhadecodigo.com.br e da revista Engenharia de Software Magazine. Autor dos livros "CVS: Controle de Versões e Desenvolvimento Colaborativo de Software" e "Automação e Gerenciamento de Testes: Aumentando a Produtividade com as Principais Soluções Open Source e Gratuitas". O autor também é criador e mantenedor do portal TestExpert, maior comunidade brasileira sobre teste e qualidade de software, confira no seguinte endereço: http://www.testexpert.com.br.