software-testing

Ao planejar um projeto, quanto tempo deve ser reservado para os testes? Não seria suficiente calcular uma porcentagem em relação ao tempo estimado para desenvolvimento? É preciso mesmo planejar isso?

No silver bullets

Não existe um método mágico e correto para estimar o tempo gasto com testes, assim como não há uma solução mágica para o problema da estimação de software.

A verdade é que mesmo especialista em testes sugerem chutar! A princípio, use um fator mágico arbitrário para determinar o tempo reservado para testes. No decorrer do projeto, ajuste a proporção conforme sua produtividade e o nível de qualidade exigido.

Valores “mágicos”

Brooks, autor do famoso livro The Mythical Man-Month, descreve no capítulo 2 sua “regra” para planejar uma tarefa:

  • 30% para planejamento
  • 20% para codificação
  • 25% para testes de componentes e testes antecipados de sistema
  • 25% para testes de sistema e de integração geral

Os valores originais estão em frações, mas adaptei para porcentagem para facilitar o entendimento. Note que os testes ocupam metade do tempo de desenvolvimento (50%), o equivalente a 2,5 vezes o tempo de codificação.

Tenho notado em minhas atividades individuais que o tempo de testes varia de 1 a 1,5 vezes o tempo de desenvolvimento, incluindo testes unitários efetivos antes da codificação cobrindo cenários com valores limite e excepcionais. Além disso, é necessário mais 1 a 1,5 vezes o tempo de desenvolvimento para testes de integração após a codificação individual.

Em resumo, posso dizer que o tempo total de testes, quando feitos adequadamente, varia entre 2 a 3 vezes o tempo de desenvolvimento. Minha observação pessoal corresponde às observações de Brooks.

Pressa: e se não testarmos?

A dura realidade é que nem todos se dão ao luxo de separar tempo suficiente para testar. O termo “luxo” aqui foi usado com um pouco de ironia, porque a verdade é que, em última análise, isso é uma questão cultural da empresa e do indivíduo. Não, não tem tanto a ver com o cliente, porque a qualidade do sistema não é responsabilidade dele.

É responsabilidade dos profissionais de TI fazer o que for necessário para garantir o sucesso do projeto de software para o bem da própria empresa e do cliente, mesmo que as demais áreas não compreendam isso. Se a qualidade exigida não for financeiramente viável, então o projeto como um todo não está bem formulado ou simplesmente deve ser arquivado.

Tenho algumas considerações importantes que talvez possam ajudar:

  1. O tempo investido em testes unitários antes da codificação efetivamente diminui o tempo de codificação, já que o desenvolvedor tem que considerar cuidadosamente as entradas e saídas. De outra forma, as pessoas tendem a iniciar a codificação de um módulo do programa sem a noção do todo e precisa constantemente revisar o que já fizeram ao se deparar com novos detalhes e requisitos.

  2. Criar testes antes da codificação pode ajudar muito no entendimento do problema, já que o desenvolvedor precisa entender os requisitos para validar os resultados através de asserções.

  3. Em projetos “legados”, que não possuem testes unitários ou automatizados, o tempo gasto com correções tende ao infinito, pois a taxa de erros nunca estabiliza. Sem testes, não podemos mensurar corretamente o impacto das alterações e correções. A cada passo para frente, damos dois para trás. Uma correção pontual pode causar efeitos colaterais não esperados em outras funcionalidades.

  4. Uma premissa falsa que muitos tomam por verdadeira é que se as partes de um sistema forem implementadas corretamente, então não haverá problemas ao juntá-las no final. Isso é sempre um erro. Mesmo grandes desenvolvedores que sempre criam código de qualidade não podem evitar testes de integração, de sistema e de aceitação.

  5. Quanto mais tarde um erro for descoberto, maior o custo para corrigi-lo. Quanto antes os testes entrarem em ação, mais cedo eles podem contribuir para encontrar esses erros e problemas em potencial. Considere a imagem abaixo, extraída do artigo The Incredible Rate of Diminishing Returns of Fixing Software Bugs:

cost-fix-project

Um tempo bem gasto com testes permitirá aos desenvolvedores terem um horizonte visível do que é esperado do sistema.

Sobre estimação de software

Em minha pós-graduação, desenvolvi uma monografia sobre estimação de software. No momento em que escolhi este tema, acreditava que iria encontrar um método mágico para determinar o tempo das atividades de um projeto. Obviamente, logo que comecei a pesquisa percebi que havia acreditado num grande engodo.

Um dos livros mais interessantes de minha bibliografia foi Software Estimation: Demystifying the Black Art de Steve McConnell, cujo título já esclarece muito sobre a essência das estimativas: elas são tentativas de prever o futuro. Estimativas são chutes, simples assim.

A consequência disso é que não existe, e nunca existirá, uma regra definitiva para estimação das atividades de desenvolvimento de software. Na verdade, métodos “matemáticos” de estimação (COCOMO, Function Point) acabam confundindo seus usuários no sentido de que estes acreditam que o resultado terá acurácia garantida, afinal há todas aquelas fórmulas matemáticas complicadas. Aliás, é comum confundirmos acurácia (resultado bom) com precisão (nível de detalhe, casas decimais), mas uma estimativa pode ser muito precisa, porém longe da realidade.

Em decorrência disso, as metodologias ágeis não usam valores absolutos para estimar, como horas e dias, mas story points (pontos de história), que são grandezas relativas que variam de acordo com a equipe, o projeto e maturidade do desenvolvedor.

Os métodos mais modernos também não buscam precisão, isto é, estimar em muito detalhe (horas, por exemplo), já que frequentemente isso diminui a acurácia. Estimar em dias, semanas ou, em alguns casos, meses pode parecer “bruto” demais, porém os resultados são mais realistas. Não concorda? Então pense: quão confiável é uma estimativa de 370 dias e 4 horas? Sinceramente, alguém pode prever tudo o que ocorrerá em praticamente um ano?

Então, cuidado com soluções mágicas que podem tentar lhe vender. Embora algumas técnicas de estimação pareçam melhores, na verdade ninguém pode afirmar absolutamente que determinado método é melhor. Fazer isto seria o mesmo que afirmar que você tem um método para jogar na loteria melhor que outras pessoas, sendo o resultado simplesmente aleatório.

Leia algumas conclusões adicionais sobre estimação de software no artigo Reflexões sobre a natureza do software e das estimativas de software.

Mas isso significa que devemos sempre “chutar” durante o planejamento? Claro que não! Podemos chutar com estilo. 😉

Estimação por analogia

Estimar é prever o futuro. Porém se as atividades de desenvolvimento de um novo projeto são análogas a experiências anteriores, os envolvidos podem ter uma boa ideia do esforço necessário para executá-las.

Isso não acaba com os imprevistos, nem garante um cronograma em dia, mas resultados empíricos mostram que uma técnica adequada e a experiência do planejador contribuem para melhores estimativas.

Uma outra abordagem indicada pelos autores e especialistas em estimação é medir e armazenar a produtividade da equipe para então projetar os resultados futuros. Individualmente, este é um dos principais objetivos do PSP (Personal Software Process ou Processo de Software Pessoal). Um dos pilares do Scrum, a Inspeção, deve permitir acompanhar o progresso e a produtividade da equipe.

Embora a estimação, tanto dos testes quanto das demais atividades do desenvolvimento de software, seja uma tarefa mais de intuição do que um processo científico, em geral observa-se uma melhora na qualidade das estimativas com o uso sadio de dados históricos e analogia das atividades novas com as já executadas.

Uma aplicação prática disso para os teste é muito simples. Imagine um cenário onde você entregou a versão inicial do produto e irá partir para a segunda fase de um projeto de N fases. Se você mediu o tempo gasto com os testes na primeira fase, calcule o desvio com relação ao tempo planejado e aplique-o no planejamento da segunda fase. O processo deve ser repetido a cada fase do projeto.

Note que isso é compatível com o conceito do Cone da Incerteza, o qual afirma que as estimativas são melhores a cada fase do projeto. Considere a imagem abaixo, extraído deste artigo):

cone-da-incerteza

Na medida em que o projeto se desenrola, em tese, podemos analisar com mais certeza o horizonte de sua conclusão. No entanto, a curva não é a mesma para todo projeto e empresa. Os autores afirmam que a curva acima é o caso ótimo e se não houver gerenciamento adequado a incerteza continuará grande mesmo na data de término do projeto!

Estimação em faixas

Isso nos leva a outro conceito: estimar em faixas de valores. Podemos usar esta técnica para estimar o melhor e o pior caso para uma determinada atividade. A diferença entre esses casos corresponde à incerteza atual.

Tenho usado faixas de valores para trabalhos como consultor independente e tem funcionado bem, principalmente em atividades que envolvem algo novo para mim, portanto não sei ao certo quanto tempo será necessário de pesquisa, desenvolvimento e testes.

Num exemplo simples, posso responder que a atividade poderá levar de 8 a 12 horas. Se tudo correr bem, pode ser até até menos. Se tudo der errado, talvez eu tenha que negociar horas a mais. Na maioria das vezes consigo acertar e cobro algo dentro da faixa.

Isso também permite ajustes relacionados a reuniões e telefonemas. Se em um projeto passei duas horas no telefone com o cliente, esse tempo é incluído no tempo da atividade. Se o cliente especificou bem a tarefa e não foi necessário muito tempo de análise, bom para ele, vai pagar menos.

É claro que isso envolve uma relação de confiança por parte dos clientes, mas a ética do profissional cedo ou tarde torna-se patente.

Estimativa ou compromisso?

Outro erro comum no dia-a-dia é confundirmos estimativas com compromisso por parte dos desenvolvedores.

Imagine que uma empresa estima os testes com uma regra mágica de 50% do tempo de desenvolvimento. Os desenvolvedores percebem que estão gastando muito mais do que isso.

Uma reação comum para não “atrasar o cronograma” é simplesmente escrever menos testes do que o planejado, como se a estimativa inicial fosse uma obrigação a ser seguida.

O correto seria revisar a estimativa inicial e não tentar se ajustar a ela. O problema é que na prática…

Frequentemente falta aos gerentes de software firmeza de fazer o pessoal esperar por um bom produto (Brooks)

A qualidade é um fator determinante

Usei a citação acima em um artigo sobre o Triângulo de Ferro que escrevi há algum tempo. Este conceito é importante pois demonstra que a qualidade possui uma relação direta e proporcional com o tempo despendido no projeto.

Isso implica em afirmar que mais qualidade exige mais tempo. Por isso, a decisão de investir em mais ou menos testes no início do projeto influenciará diretamente na qualidade final do produto.

Diminuindo o tempo despendido com testes sem prejudicar a qualidade

O título parece contradizer o que acabei de dizer. Mas, se tomarmos o conceito de separação entre atividades essenciais e acidentais do desenvolvimento como faz Brooks em No Silver Bullets, podemos dizer que, embora não haja como evitar os testes sem diminuir a qualidade, podemos diminuir as dificuldades acidentais da criação deles.

Isso pode ser alcançado de algumas formas:

  • Treinando a equipe para melhorar a produtividade
  • Usando ferramentas mais adequadas que facilitem a criação e execução dos testes
  • Investindo na automação
  • Usando tecnologias (frameworks, plataformas) que facilitem os testes

Enfim, podemos ser mais produtivos fazendo mais testes e menos trabalho repetitivo manual.


Este artigo foi baseado na minha resposta no StackOverflow em Português!