papo de desenvolvedor – por que testar?

este artigo foi publicado originalmente na revista mundo .net, edição 11. infelizmente esta revista foi descontinuada. resolvi publicar o artigo original.


  • “Teste, Teste, Teste”
  • Para que serve o teste?
  • Os Mitos
  • Por que são mitos
  • O que os testes são
  • O que ter em mente
  • Considerações Finais

Após algumas edições sem aparecer, estou de volta a Mundo .NET. E com uma nova coluna. O objetivo desta coluna é falar de tudo que interessa a um bom geek e de preferência como se fosse um bate papo de botequim. Algumas vezes vou falar sobre questões relacionadas ao ciclo de desenvolvimento de software (como nesta edição). Outras vezes vou falar sobre algum aspecto interessante de uma tecnologia. Enfim, tudo que possa interessar a um bom desenvolvedor.

Deixo a coluna radar .Net em boas mãos. Meu amigo Rogério Cordeiro, que é Especialista em desenvolvimento aqui na Microsoft, vai assumir a coluna a partir da próxima edição. Tenho certeza que vocês continuarão achando as novidades bem interessantes. Entretanto, estou bem excitado com as possibilidades desta nova coluna.

1 “Teste, Teste, Teste”

Teste. Qualidade de software. Teste unitário. Ferramentas para automatizar o seu teste. Code Coverage. Como temos escutado estas palavras ultimamente entre os desenvolvedores que utilizam .NET. Acredito que todos saibam que nada disto é novo ou o conceito definido recentemente.  Nem mesmo ferramentas para automatizar os testes são recentes. Consigo me lembrar de imediato de pelo menos duas empresas de grande porte que vendiam soluções interessantes para atender esta necessidade.

Mas, talvez pela popularização de algumas ferramentas de teste unitário de código aberto ou pelo surgimento de ferramentas específicas para testes integradas com o Visual Studio, temos visto cada vez mais desenvolvedores falarem sobre isto no Brasil (quando falo em desenvolvedores, me refiro aos desenvolvedores que utilizam principalmente .NET). Nesta mesma revista tivemos alguns artigos sobre o Visual Studio Team Edition para Testers. Basta procurar na internet e encontrará diversos blogs, vídeos e tudo mais que for possível imaginar sobre teste.

Com isto, testes unitários passam a ser criados pelos desenvolvedores. Times de testes são formados para garantir a “qualidade” do software que está sendo produzido.

Num primeiro momento poderíamos dizer: “Que ótimo!”. “Finalmente estamos dando a atenção necessária que a qualidade de software merece”, outros poderiam dizer.

Infelizmente, às vezes, eu fico um pouco preocupado com este cenário.

2 Para que serve o teste?

Antes de continuar lendo, pare por alguns segundos e responda a esta pergunta: para que serve o teste? Você deve concordar comigo que para fazermos ou usarmos qualquer coisa bem, precisamos saber o seu objetivo ou propósito.  Se eu quero criar testes para o meu software preciso saber o que quero alcançar com eles. O que eles vão me indicar.

Já ouvi uma pessoa escrevendo um teste unitário dizer que o objetivo do teste que ele iria escrever era mostrar que o pedaço de código testado estava certo. Já outro achava que os testes iriam garantir que o software estava livre de erros e bugs. Não é incomum acharmos alguém que ache que teste realizado e que logo no primeiro resultado não aponta bugs é um bom teste. Já outros acreditam que enquanto os testes não cobrirem 100% dos possíveis caminhos na aplicação, o software não deveria ser considerado pronto para o mercado.

Infelizmente todas estas visões sobre o que é um teste e qual o seu objetivo estão deturpadas.

O simples fato de usarmos uma ferramenta de teste unitário ou o VSTS não garante que teremos “bons” testes e que o nosso software terá qualidade.

Portanto, o ponto de partida para se desenvolver um bom teste é entender para que o teste serve. Qual é o seu real objetivo. O que se pode esperar de um bom teste. O que é um teste ruim. Quais são os erros mais freqüentes neste sentido.

Entender cada um destes pontos é fundamental antes de pensarmos em qual documentação usar, que tipos de testes realizar, automatizá-los ou não e qual será a cobertura de código ideal.

Vamos entender primeiro o que o teste não é por analisar alguns mitos relacionados com ele. Depois vamos entender porque são mitos. E então, qual é o objetivo dos testes.

3 Os Mitos

Existem três grandes mitos relacionados a testes. O primeiro, e talvez o maior, é a crença de que os testes podem verificar um software completamente.

O segundo é de que os testes garantem que o software funciona corretamente. E que o objetivo é provar a ausência de erros.

O terceiro é pensar que o código do software falha, mas que o código de teste nunca falha. Ou simplesmente nos esquecemos que ele também pode falhar.

Estes mitos, ou crenças, se tornam uma fonte de fé para muitos ao escreverem testes. E por isto os conceitos ficam tão deturpados. Estes mitos podem trazer muitas dores, frustração e trabalho para os que creem ou tem fé neles.

4 Por que são mitos

A crença de que um software pode ser verificado completamente é um mito simplesmente porque é praticamente impossível verificar todas as possibilidades de um software. Para entendermos isto, vamos imaginar um simples programa que é executado utilizando linha de comando. Este pequeno aplicativo soma dois números (x) positivos, diferentes de zero e menores que 100 (0 < x <100). Se agora queremos testar todas as possibilidades dos números que serão somados teremos 9801 combinações diferentes para verificar. Imagine então se a nossa calculadora agora aceitar números até 99.999.  Teremos então quase 10 bilhões de possibilidades. Isto apenas contando os valores válidos. Para verificar completamente um sistema, teríamos que testar os valores inválidos também.

Além disto, todos os caminhos possíveis do código deveriam ser verificados. Glenford J. Myers, em seu livro Software Reliability: Principles & Practices (1976), demonstrou e descreveu um programa com apenas 100 linhas de código que tinha 1018 caminhos possíveis. Podemos imaginar quanto código de teste precisaria ser escrito e quanto tempo levaríamos para verificar todos os caminhos possíveis. Podemos acrescentar a esta lista os testes que precisariam ser feitos para ações inesperadas como abortar o processo no meio da execução, pausá-lo e muito mais.

Esta rápida análise do primeiro mito nos ajuda a entender porque a segunda crença também é um mito. Se todas as possibilidades e caminhos de código possíveis não podem ser testados, não se pode afirmar que o software sempre funcionará corretamente. E não deveríamos colocar nossas esperanças de alcançar isto nos nossos testes. Justamente por isto, o renomado e premiado Edsger W. Dijkstra certa vez disse: “Os testes dos programas podem ser usados para mostrar a presença de bugs, mas nunca para mostrar a sua ausência”.

E para perceber o terceiro mito, basta lembrar que os testes também são rotinas ou programas que foram desenvolvidos. Estão sujeito a falhas e erros como qualquer outro código, como erros de digitação ou de lógica. Eles precisam ser desenvolvidos com cuidado e também são fonte de falhas.

Para Saber Mais


Edsger W. Dijkstra: http://en.wikipedia.org/wiki/Edsger_Dijkstra


Software Reliability: Principles & Practices; ISBN: 0471627658

5 O que os testes são

Os mais pessimistas podem agora estar se perguntando por que testar, já que, não vamos conseguir evitar os erros. É claro que não precisamos ir ao outro extremo. Os testes ainda são um aspecto importante para qualidade de software. E, infelizmente, em muitos casos a única ferramenta usada com este objetivo.

O objetivo de um teste é verificar um cenário e tentar encontrar o maior número de bugs possíveis. Encontrar erros e de preferência erros graves. E então corrigi-los. Corrigir os bugs é que aumenta a qualidade do software e não os testes em si mesmo.

Portanto, testes bem desenvolvidos e com o objetivo correto em mente são fundamentais para melhorarmos a qualidade do nosso software. Ou a qualidade percebida pelos usuários.

6 O que ter em mente

Achar um bug é um objetivo que vai de encontro com o objetivo do desenvolvedor quando escreve seu código. O desenvolvedor escreve um código para funcionar, obviamente. Isto pode tornar o seu teste unitário ou de componente potencialmente perigoso. Isto porque, a sua tendência natural é escrever um código de teste que prove que o código do software está correto.

Muitos erros serão deixados para trás ou passarão despercebidos se um teste iniciar com a premissa de que o código está certo. Diversos estudos psicológicos demonstram como podemos ver ou deixar de ver alguma coisa de acordo com o que preparamos a nossa mente anteriormente. O próprio Glenford Myers, citado anteriormente, realizou um estudo que se tornou clássico, onde desenvolvedores experientes foram convidados a testar um programa com 15 erros conhecidos. Como resultado foi encontrado apenas cinco erros em média. E o maior número encontrado foi de nove erros. A maior parte dos erros estava em uma rotina que não foi examinada com cautela. Isto deixa claro que o teste do desenvolvedor tende a pular alguns tipos de coberturas mais sofisticas. Com isto, erros são deixados para trás.

Porém, o outro lado também é verdade. Um testador que acredita que encontrará muito erros em um cenário poderá também encontrar falsos bugs. Por isto, os bugs precisam ser verificados novamente e analisados calmamente antes de serem relatados.

Se quisermos encontrar os erros para então corrigi-los, não queremos testes que dão resultados positivos deste o primeiro momento. Isto pode indicar uma falha séria no teste. Imagine que você está sentindo muitas dores no peito e então vai a um médico. Este médico faz uma bateria de exames e no final todos indicam que você está bem. Mas, você continua sentindo as dores. Neste caso, só teríamos duas opções. Ou este médico fez os exames errados, ou você desperdiçou tempo fazendo-os. Como você ainda sente as dores, provavelmente a primeira opção é a verdadeira. O mesmo se dá com os testes. Os bugs estão lá. Basta fazer os testes certos para encontrá-los.

Alguns estudos indicam que a média é de 1 a 25 erros por 1000 linhas de código (McConnell, Steve. Code Complete: um guia prático para construção de software).Mas, isto pode variar bastante de empresa para empresa e de técnicas e metodologias utilizadas durante o desenvolvimento.  Mesmo assim, nenhuma técnica reduz este número à zero.

Os testes podem ser classificados em dois tipos: “testes sujos” e “testes limpos”. Os “testes limpos” são os que verificam as condições que irão funcionar. Os “testes sujos” são os que verificam os cenários e condições que não irão funcionar. Portanto, testes bem escritos são os que encontram o maior número de falhas possíveis. Estes testes precisam ser escritos com cuidado, focando nos pontos onde existe maior probabilidade de haver um erro. Existem técnicas conhecidas e amplamente utilizadas que nos ajudam a criar identificar e cobrir estes pontos.

Estudos mostram que as empresas que ainda são inexperientes em testes têm em média cinco “testes limpos” para cada “teste sujo”. Já as empresas mais experientes conseguem aumentar 25 vezes o número de “testes sujos” e chegam à proporção de cinco “testes sujos” para cada “teste limpo” (“Dr. Boris Beizer on Software Testing: An interview Part 1 and 2, Johnson, Mark. 1994 The Software QA Quarterly). Não resta dúvida que, neste caso, o tempo de execução de testes é mais bem empregado. Mais erros são encontrados. E possivelmente a qualidade é maior.

Para Saber Mais


Karner, Cem, Jack Falk e Hung Q. Nguyen. Testing Computer Software, 2ª ed. New York, NY: John Wiley & Sons, 1999. ISBN 0-471-35846-0


McConnell, Steve. Code Complete: um guia prático para construção de software; tradução João Tortello. – 2ª Ed – Porto Alegre : Bookman, 2005. ISBN 85-363-0504-5

Fiz um breve post sobre este assunto em meu blog. O objetivo é receber opiniões e iniciar uma discussão sadia sobre o tema. Se desejar expressar sua opinião sobre o tema, deixe seu comentário no post (http://blogs.msdn.com/cguimar/archive/tags/Desenvolvimento/default.aspx).

Considerações Finais

Obviamente isto é apenas a ponta do iceberg. Apenas falamos sobre qual objetivo dos testes e o que devemos ter em mente antes mesmo de começar a escrevê-los. Porém, existem diversos diferentes tipos de testes que podem ser feitos. Metodologias que defendem a necessidade de os testes serem escritos antes mesmo do código que será alvo do testes. Existem algumas sugestões e métodos sobre onde concentrar os testes para serem mais objetivos. Todos estes assuntos naturalmente se transformam em diversos papos de desenvolvedores.

Leva tempo para se tornar experiente em realizar testes efetivos e ter uma boa proporção de “testes sujos” para “testes limpos”. A prática contínua é que levará à experiência. Porém, aprendermos um pouco com a experiência de outras pessoas e empresas poderá acelerar o nosso processo de amadurecimento. Portanto, vale a pena pesquisar mais sobre o tema com quem realmente entende do assunto.

Até mais!