Daine Azevedo de Fraga
Daine Azevedo de Fraga, Software Engineer na Umbler

Qualidade de Software #1: 7 motivos para considerar o teste de software indispensável

Este é o primeiro de uma série de posts que irá falar sobre qualidade de software. Antes que você saia correndo ao achar que vamos falar sobre teorias intermináveis e processos enfadonhos, segura aí. Preparamos uma forma especial para falar com você sobre esse assunto.

Vamos imaginar uma casa. Ela é composta basicamente de alicerce, paredes e telhado. Então, vamos usar essa analogia para compor a nossa abordagem:

  1. Motivação: nosso alicerce será acreditar no processo de garantia da qualidade através do teste de software.
  2. Conhecimento: nossas paredes serão o conhecimento das técnicas, processos e premissas da qualidade de software.
  3. Prática: nosso telhado será a propriedade sobre o porquê e o como, levando-nos naturalmente a executar o que, agora, conhecemos.

Vamos começar? No nosso primeiro post iremos apresentar a motivação.

O que é qualidade?

Vamos começar pelo conceito de qualidade. Você já deve ter pensado nesse conceito várias vezes. E isso provavelmente ocorreu antes de adquirir um produto ou um serviço, certo?

Pois é, se pensarmos a respeito, veremos que nem sempre os nossos critérios de qualidade são claros. Assim, quando pensamos em qualidade, acabamos por nos expressar de diversas maneiras diante das situações que nos são impostas. Por exemplo:

  • “Este produto é de qualidade. É visível que ele foi bem feito.”
  • “Uau! Que serviço de qualidade, muito bem executado!”
  • “Isso é de muito bom gosto, de excelente qualidade.”
  • “Recomendo esse serviço para todos que conheço! É um serviço de ótima qualidade e me atende perfeitamente.”

As frases acima expõem diferentes expressões relacionadas a aspectos de produtos e serviços. As pessoas que falam expõem percepções sobre o processo de fabricação, a aparência do produto, o atendimento de uma necessidade. No fim, você observou que todas as situações expressam, de uma forma ou de outra, o sentimento de satisfação? Pois é, isso não é coincidência. 🙂

Qualidade, de modo geral, está diretamente relacionada às expectativas dos clientes. Assim, quanto mais um produto ou um serviço atende às expectativas, maior é o grau de satisfação dos seus clientes. Por isso, normalmente existe uma considerável preocupação com a experiência dos usuários e consumidores. A percepção do cliente quanto ao atendimento de suas necessidades e de seus desejos é equivalente a sua percepção de qualidade. E isso é fundamental para o sucesso do negócio.

Qualidade → Satisfação

Satisfação → Expectativas atendidas ou superadas

A premissa básica de qualquer produto sempre é que ele tenha qualidade. Isso porque quando adquirimos um produto ou um serviço nós esperamos que ele atenda nossas expectativas, sejam elas explícitas ou implícitas.

Uma definição muito interessante é citada por Andrii Dzynia, que trabalha como Engineering Coach na Spotify, em sua apresentação intitulada Quality Built In:

Quality is a ‘state’… when expectations match the reality.

Então, por que qualidade é importante?

Vamos analisar um exemplo da vida real: uma pessoa vai até o mercado e adquire um pote de mostarda para colocar naquela pizza de sardinha que vai preparar em casa. Ela sempre compra a mostarda da mesma marca, porque sabe que suas expectativas são atendidas quanto ao sabor, aroma, consistência, embalagem e conteúdo (o que tem dentro do pote é realmente mostarda).

A partir desse exemplo, somos levados a pelo menos três conclusões:

  • Qualidade leva à confiança. Se o cliente acredita na qualidade, isso faz com que ele confie no produto e volte a adquiri-lo.
  • Confiança leva à popularidade. Aposta quanto que o cliente do exemplo acima já não comentou com a família ou com os amigos sobre a marca da mostarda que ele tanto gosta? 🙂
  • Capacidade de produzir com qualidade leva à confiança na marca. O cliente confia que as pessoas que estão envolvidas na produção do produto ou na execução do serviço são capazes, responsáveis e seguidoras das melhores práticas. É a confiança no produto sendo levada para a marca.

Logo, a percepção de qualidade de seu produto está relacionada ao número de novos clientes que você ganha, ao número de clientes que permanecem consumindo seu produto (ou contratando seu serviço), e ao número de clientes que falam bem de sua marca. E novamente, tudo está relacionado ao atendimento das expectativas de quem está do outro lado do balcão. 😉

Com software não é diferente. Podemos fazer vários paralelos com produtos e serviços de software. No fim, chegaremos nas mesmas conclusões. Qualidade é um dos fatores decisivos não apenas para a sobrevivência, mas também para o total sucesso do seu negócio. Por isso, qualidade é importante! 🙂

E o teste? Por que ele é importante?

Qualidade é um conceito subjetivo. De fato, mesmo no mundo do software, qualidade está relacionada às pessoas, sejam elas usuários, stakeholders, testadores, ou desenvolvedores. E se está relacionado às pessoas, sempre teremos margem para ambiguidades, conceitos relativos, aspectos culturais e opiniões divergentes. Então, com toda essa subjetividade, como saber que seu software atende aos padrões de qualidade esperados?

Basicamente, o teste de software visa garantir a qualidade, minimizando as incertezas e sistematizando os critérios de aceitação. Ele ajuda a validar se: as expectativas de todas as pessoas envolvidas estão sendo atendidas (e estão alinhadas); o software apresenta um bom funcionamento (parte disso está relacionada às expectativas implícitas – aquilo que é inerente ao produto). Além disso, o teste também possibilita realizar verificações complexas que um ser humano não conseguiria executar (pelo menos, não facilmente).

Contudo, teste não é um puro sinônimo de qualidade. Simplesmente executar testes não significa que o software atende a todos os critérios de qualidade. Os testes também precisam de um ciclo de planejamento, desenvolvimento, execução e manutenção. E se essas fases não forem executadas com o mínimo de cuidado, a consequência pode ser resultados não confiáveis, verificações equivocadas e o abandono da prática do teste. Por isso, estude, explore e questione seus testes assim como você faz com seu sistema. Isso levará você a aprimorar o entendimento dos requisitos e a forma escolhida para atendê-los. Acreditamos que um dos mais importantes benefícios do teste de software é fazer você pensar diferente, suscitando perguntas que você não teria feito em outros momentos. E isso enriquece o seu projeto.

A garantia de qualidade deve acompanhar o software desde a sua concepção até sua manutenção. E durante todo o ciclo de vida dele, todos os envolvidos tornam-se responsáveis pela qualidade. Então, o teste nos ajuda a sistematizar a garantia dessa qualidade.

Se você ainda não está convencido que possuir um processo que inclua teste de software é indispensável, calma aí. Agora, vamos apresentar a você sete ótimos motivos para isso, os quais representam benefícios que são trazidos para o seu projeto a partir dessa prática:

1. Alinhar as expectativas

A pergunta que o teste ajuda a responder aqui é: Funciona como o cliente espera?

Quando testamos, precisamos nos perguntar sobre o que nosso software deveria fazer, isso porque precisamos saber o que testar. Assim, principalmente os testes focados em aspectos funcionais e comportamentais, evidenciam desalinhamentos entre o que os usuários esperam e o que está sendo produzido. Se o usuário quer um sistema que permita a ele cadastrar fotos e descrições da sua coleção de bonsais, o sistema não deveria oferecer um gerador de memes?

Olhar para as especificações em frente ao resultado final, somente de modo arbitrário, raramente é o suficiente para percebermos expectativas não atendidas ou mal interpretadas. Ao planejar, escrever e executar os testes, somos impelidos a questionar e a reinterpretar aquilo que foi descrito como requisito do sistema. Assim, esse exercício frequentemente revela problemas na escrita e na interpretação da especificação, além de problemas no próprio entendimento das pessoas envolvidas no projeto.

Vale lembrar que no centro de todos os propósitos está a satisfação do cliente. Logo, é a expectativa dele que precisa ser atendida. Por isso, quando planejamos e escrevemos um teste, e também quando interpretamos o resultado dele, a pergunta que sempre deveríamos fazer é: essa situação está de acordo com o que o usuário do meu sistema espera?

“Eu tinha certeza que o usuário queria assim, mas agora não sei mais.” 🙁

Provavelmente isso fará com que você revisite a especificação, consulte novamente os stakeholders, faça um novo teste com um usuário. E no fim, você terá realizado um incrível exercício de amadurecimento de seu projeto.

2. Pegar o defeito antes do cliente

A pergunta que o teste ajuda a responder aqui é: Funciona como o desenvolvedor espera?

O que acontece normalmente é que você, no papel da pessoa que desenvolve, assume sempre que desenvolveu certo :). Mas você deve concordar que é humanamente impossível testar todas as possibilidades existentes durante o funcionamento de um sistema complexo. Ainda mais, sem uma técnica clara e bem definida. Em outras palavras, se já é difícil impossível detectar todos os defeitos com testes adequados, imagina sem! 😮

Mas antes que você fique bravo comigo, não estou dizendo que você não sabe programar! Defeitos sempre irão existir, e podem se manifestar em situações que nunca haviam sido previstas. Então, podemos usar as características sistemáticas dos testes a nosso favor para minimizar esses problemas! Diferentes níveis de teste levam a diferentes níveis de captura de defeitos. E testes automatizados, mais do que qualquer outra instrumentação, são uma forma muito confiável de verificação contínua do software.

Quem nunca passou por uma situação do tipo “Tinha certeza que esse erro nunca iria ocorrer! Como eu iria adivinhar que a atualização dessa biblioteca iria mudar o tipo do dado após esse parser?”

Pois bem, sempre irá ocorrer uma situação que foge ao controle de quem desenvolve. Não podemos confiar na sorte. Então, precisamos usar ferramentas adequadas para garantir que qualquer alteração, e também novas implementações, não estejam guardando surpresas desagradáveis. E manter uma boa cobertura de testes, principalmente os automatizados, é uma das melhores ferramentas para isso.

3. Detectar problemas de design da aplicação

A pergunta que o teste ajuda a responder aqui é: Você anda questionando seu projeto?

Com certeza, além de técnicas como code review e pair programming, o desenvolvimento de testes a nível de código é uma das formas mais baratas e rápidas de detectar problemas comportamentais e estruturais de seu software. Isso se deve essencialmente à necessidade de tornar o software testável, o que leva a questionamentos sobre a implementação. Consequentemente, você passará mais tempo tomando café em meio a refatorações aderentes a padrões de projeto, boas práticas, clareza, objetividade e… testabilidade. 🙂

Normalmente se costuma falar em testes de unidade, com os quais se verifica a menor unidade de código testável do software. Mas outros níveis de teste também ajudam a verificar não apenas se o funcionamento do software está de acordo com o esperado, mas também se a forma usada para alcançar os objetivos é a mais adequada. Sabe aqueles code smells? Pois é, o teste te ajuda com isso também. 😉

Por exemplo, um teste de performance poderia ajudar você a identificar a necessidade do uso de uma cache. Um teste de unidade poderia indicar que o princípio de responsabilidade única está sendo ferido em algum ponto. Um teste de integração poderia evidenciar o uso inadequado de uma interface. Um teste de componentes poderia alertar sobre uma interação desnecessária entre unidades.

Se você já desenvolveu algum tipo de teste de software, já deve ter passado por algum momento que parecia impossível fazer aquele teste, não é? Se você concordou, essa foi a hora certa para rever sua implementação. Saiba que quando o teste está muito (muito mesmo!) difícil de desenvolver, é um forte indício de que o design de seu sistema pode estar torto. Revise, questione, desentorte e tente novamente. 🙂

4. Manter o sistema estável

A pergunta que o teste ajuda a responder aqui é: Você está tendo surpresas com seu software?

Possuir uma estratégia de testes adequada, entre outras coisas, oferece uma verificação bem estruturada de seu sistema e o benefício de garantir seu funcionamento adequado. Mas o que faz brilhar os olhos mesmo são os testes automatizados!

Com automação de testes você pode alcançar uma execução muito confiável. Imagina você tendo vários testes automatizados que consegue executar a cada alteração de seu software? Sim, é mágica pura! Você consegue detectar os temidos bugs assim que eles aparecem. Você consegue dormir melhor, e os pequenos infartos que você tinha durante o dia diminuem.

Uma situação muito comum é a confiança no feeling. Se você trabalha há bastante tempo no mesmo projeto, já deve conhecer cada if e for como a própria palma da mão. Mas mesmo assim, você é um Tiamat de uma cabeça só, e fica muito difícil prever todas as partes do sistema que podem ter sido afetadas. Sem critérios bem definidos de verificações, é provável que uma nova versão vá para produção com alguns bugs intrometidos.

Se você reunir a galerinha da pesada dos testes automatizados, da cobertura inteligente de código e da alta frequência de execução, eles irão se meter em muitas aventuras e em muita confusão. Mas no fim da brincadeira, eles vão te ajudar a ter um software mais estável.

5. Melhorar a manutenibilidade do sistema

A pergunta que o teste ajuda a responder aqui é: O quão fácil é manter e testar o seu software?

Em poucas palavras, um sistema com alto grau de manutenibilidade é um reflexo de sua testabilidade. Simples assim? Quase…

Na verdade, se revisitarmos as outras motivações aqui citadas, veremos que o teste é um exercício que ajuda você a desenvolver o certo e da forma certa. Então, se você refatora seu sistema, busca as melhores práticas, elimina os code smells, existe uma grande probabilidade de que seu software seja algo fácil de manter.

A prática do teste, incluindo planejamento, criação e execução, fará com que você se pergunte: “E agora, como vou fazer para alterar essa parte do sistema? Preciso dar manutenção nesse pedaço de indignação, mas sei que terei que refazer TODOS os testes. Que vida injusta!” Só tenho uma coisa a te dizer: medo. Se você chegou nessa situação, é provável que seu sistema não seja muito fácil de alterar. Talvez você devesse buscar alguma melhoria de arquitetura de seu software, buscando uma maior facilidade de manutenção do seu sistema.

Mas espera aí! Como que você chegou na situação acima se você faz teste? Ah, veja bem, o teste não age sozinho. Ele vai ajudá-lo a perceber problemas e más práticas, mas não vai aprisioná-lo nas masmorras de Asgard e obrigá-lo a fazer certo, sempre. Muita coisa ainda vai depender de seus skills de bom desenvolvedor. 😉

6. Tornar o trabalho colaborativo mais seguro

A pergunta que o teste ajuda a responder aqui é: Você não está quebrando o seu colega, certo?

Raramente você estará desenvolvendo sozinho. É muito comum que você esteja dividindo o trabalho com outras pessoas. Mas já não lhe aconteceu de fazer uma alteração e isso afetar outra parte do código que seu colega havia acabado de desenvolver? E daí ele simplesmente lhe lançou uma maldição de mil anos?

Pois bem, ter uma cobertura de testes adequada lhe oferece maior segurança ao fazer uma alteração. O mundo perfeito é aquele onde podemos alterar aquela parte crítica do nosso software, executar os testes carinhosamente criados e disponibilizados, e ter um grau considerável de certeza que não afetamos as demais partes do software.

Do mesmo modo, vamos supor que alteramos uma conversão de string removendo algum caractere que antes era concatenado. Sem testes, e talvez apenas com nosso feeling, podemos simplesmente verificar que a nossa parte funciona. Então, vamos promover para produção! Uhu! Logo após 10 minutos em operação, seu colega descobre que você removeu uma substring essencial para o funcionamento daquela consulta no banco de dados que ele levou 14 dias para deixar linda. Pronto, você acabou de adquirir mais mil anos de maldição.

Desenvolva com consciência. Diga não às alterações sem teste!

7. Garantir a entrega

A pergunta que o teste ajuda a responder aqui é: O seu software está sempre funcionando?

Como um filósofo, você poderia perguntar: o que significa dizer que o software está funcionando?

Então, te respondo: vá ler o restante do post. 🙂

Falamos sobre expectativa e satisfação dos usuários, critérios de aceitação, verificações e validações. Pois bem, garantir a sua entrega é assegurar que esses senhores estejam sendo respeitados. E mais uma vez, você precisa contar com a galerinha do barulho: testes automatizados, cobertura de código e execução frequente.

Pense conosco, se você está com as expectativas alinhadas, detecta os defeitos em tempo de desenvolvimento, está sempre melhorando seu projeto, mantém seu sistema estável, faz atualizações seguras e trabalha tranquilamente de forma colaborativa, ufa, você é naturalmente capaz de garantir cada entrega feita em seu software. E isso irá contribuir muito para a satisfação de seus usuários.

E mais uma vez o teste ajudou você a construir um software mais maduro. Uma entrega garantida é sinônimo de um sistema confiável. Prepare-se para adquirir novos usuários e para fortalecer a permanência dos antigos.

Conclusão

Pronto, agora você está convencido que teste de software é indispensável. Aposto meu Tesseract nisso! 😀

Mas lembre-se, você não está sozinho! Além de estarmos com você, a maior parte dos softwares passaram, e passam, por algum tipo de controle de qualidade. Então, existem muitos livros, materiais digitais e blogs falando a respeito das mais variadas técnicas de teste. Antes de qualquer coisa, explore! 🙂

Estamos preparando outros materiais que vão explorar mais ainda o mundo da qualidade do software. Esperamos você lá!

Daine Azevedo de Fraga
Daine Azevedo de Fraga, Software Engineer na Umbler