terça-feira, 23 de agosto de 2011

Software Bem Testado

Muito tem sido escrito sobre testes automáticos e testabilidade de software nos dias atuais. O rápido avanço tecnológico tem facilitado o desenvolvimento de testes unitários, de integração e funcionais. No entanto, o uso efetivo de testes automatizados não tem se mostrado constante nos sistemas. Na Dextra temos feito um grande esforço no sentido de usar metodologias e tecnologias de desenvolvimento que possibilitem a criação de testes automatizados em seus diversos níveis e temos entregado software com grande qualidade de testes automáticos. Mas, para isso, partimos da seguinte definição do que é “software bem testado”:

Pode-se dizer que um sistema é bem testado quando:

  • O sistema não acusa falhas em suas funcionalidades mais críticas ou quando as acusa a correção é simples e não causa impacto nas demais funcionalidades do sistema;
  • O sistema suporta novas funcionalidades ou evoluções de funcionalidades existentes sem que as funcionalidades já existentes e não alteradas sejam afetadas de forma não controlada;

Esse objetivo é ambicioso pois deve garantir que:

  1. Poucas falhas sejam encontradas, pelo menos em funcionalidades críticas;
  2. A correção das falhas seja rápida;
  3. Alterações no software não causem impacto nas demais partes do sistema, ou o impacto seja apontado por testes automatizados;
  4. Esta característica deve ser mantida durante todo o ciclo de vida do sistema, ou seja, evoluções precisam ser refletidas nos testes;

Para alcançar estes objetivos, é necessário adotar duas diferentes e complementares abordagens: Arquitetura e Processo. Uma arquitetura bem definida pode garantir que um sistema seja testável, mas não garante que ele seja efetivamente testado. Apesar do advento de novas metodologias de desenvolvimento ágil, o desenvolvedor júnior (que é o mais abundante no mercado atualmente) não cria testes voluntariamente e nem cria testes bem feitos. É neste ponto que entra um processo de desenvolvimento que garanta a codificação de testes em uma cobertura racional do sistema com o envolvimento garantido de desenvolvedores experientes na sua elaboração e revisão. Neste sentido, infelizmente, a maioria dos processos baseados em metodologias tradicionais tem falhado. E tem falhado principalmente ao definir uma porcentagem mínima de cobertura de testes, em geral denominado “taxa de cobertura”. Infelizmente este número não tem significado algum que nos permita deduzir se um software é ou não bem testado. Seguem abaixo cinco razões para evitar este tipo de solução:
  1. A taxa de cobertura não diz que o sistema funciona de acordo com o especificado, diz somente que as regras implementadas no sistema funcionam para um conjunto de testes qualquer. Ou seja, não dá nenhuma medida de quanto o software atende aos seus requisitos. Isso é relevante, pois, afinal, não seria esse o principal objetivo dos testes?
  2. A taxa de cobertura, a não ser que seja 100%, não garante que os pontos mais críticos foram cobertos pelos testes. Mas, não são exatamente estes pontos que deveriam ser testados? Em geral, o uso desta taxa em um valor qualquer diferente de 100%, por exemplo, 70%, tem o efeito exatamente contrário do desejado, fazendo com que as partes menos críticas sejam testadas (pois são mais fáceis de testar) até que a taxa seja alcançada, fazendo com que os 30% restantes e não testados sejam, muito provavelmente, as partes que mais deveriam ser testadas.
  3. A taxa de cobertura próxima a 100% multiplica quase que irracionalmente a quantidade de testes no sistema. Mesmo sem garantir nada com relação à aderência aos requisitos, esta quantidade extensiva de testes aumenta significativamente os custos do projeto e de manutenção futura do software desenvolvido.
  4. Uma baixa taxa de cobertura não garante que o software é mal testado. As partes mais críticas podem ter sido testadas à exaustão verificando os comportamentos definidos nos requisitos do sistema. Como vimos antes, ter muitos testes não é necessariamente bom, mesmo que estes testes sejam bem feitos, pois o custo de manutenção cresce bastante com o número de testes a serem mantidos.
  5. E o pior, a taxa de cobertura, por ser uma medida quantitativa, pode dar uma falsa segurança aos gestores de projeto e mantenedores de processo fazendo com que medidas efetivas para melhoria da qualidade dos testes não sejam tomadas.

Basicamente o erro está em acreditar que a cobertura do código-fonte é importante, mas não é. O importante é que existam testes onde há maior probabilidade de falha. Testes de código que nunca falham não são verdadeiramente úteis. No entanto, testar somente o que vai falhar parece paradoxalmente complexo. Testar tudo poderia ser uma abordagem para testar sempre o que vai falhar, porém esta abordagem é dispendiosa e tem efeitos colaterais indesejados. Para resolver este problema, um processo deveria, pelo menos:
  • Definir que para todo erro notificado no sistema (em qualquer fase do desenvolvimento) seja escrito um teste automático que reproduza o erro em questão em um ambiente simulado. Desta forma, existirão mais testes onde houver mais erros;
  • Definir quais partes do sistema deverão ser melhor testadas e atribuir a responsabilidade de revisão de código nestas partes para o arquiteto, projetista ou desenvolvedores mais experientes;
  • Definir que nem todos os testes elaborados durante o desenvolvimento são necessários após a finalização do desenvolvimento. O importante não é a quantidade de testes, mas a sua relevância;

Bom, em um processo que possibilite a realização destas atividades, possuir a taxa de cobertura pode não agregar muito valor, mas não retira valor do que foi realizado. O que temos visto nos projetos da Dextra é que, através destas simples diretivas, uma alta taxa de cobertura acaba sendo atingida e com grande qualidade.


Nenhum comentário:

Postar um comentário