segunda-feira, 18 de abril de 2011

Como testar quando o software não tem botões?

Texto que escrevi para o blog Bytes don't Bite!

Mencionei anteriormente da importância, para uma pessoa que trabalha com testes de software, de se ter conhecimentos sobre como desenvolver e ter uma visão do ambiente em que o software opera. Tais conhecimentos podem ser considerados facultativos para diversos profissionais de teste, mas em certos casos se tornam obrigatórios.

O que acontece, por exemplo, quando não existe uma UI para testar? Este cenário acontece quando o software desenvolvido trata-se de uma API (Application Programming Interface). O teste de API requer o desenvolvimento de uma aplicação que simule o uso real das chamadas.

Uma vez que se trata de testes de API, Josh Poley menciona que muitas técnicas diferentes serão sugeridas, dependendo do testador. Entretanto, o mesmo apresenta uma situação que funcionou bem para os testes do Sistema Operacional do Xbox.

Participei de dois projetos em que aplicações eram desenvolvidas para que o produto principal pudesse ser testado. No primeiro, o produto desenvolvido continha implementações de JSRs para um emulador de J2ME. Nos testes, então, eram criadas aplicações J2ME, que tinham a proposta de avaliar as classes definidas em cada especificação.

No outro projeto, foi criada uma API para comunicação com determinadas impressoras. Nesta aplicação, uma das funcionalidades era o envio de uma linguagem intermediária para API, que gerava um comando (PCL / PJL / HP-GL) correspondente e mandava para impressão. Para tal funcionalidade, era necessário o conhecimento das entradas e saídas esperadas (tanto da linguagem intermediária como do comando enviado para impressora). Os testes foram desenvolvidos em C++, simulando uma aplicação real que utilizaria a API.

Mas antes de começar a desenvolver os testes, é necessário dedicar um tempo para o planejamento do que será testado. Dependendo da complexidade da aplicação, um documento de testes pode auxiliar nessa atividade.

Já na criação dos testes, deve-se pensar como o ambiente pode ser preparado para identificar certas situações, como por exemplo, o uso de um arquivo corrompido ou a ausência de conexão de rede. A atividade de forçar falhas, em uma aplicação, pode ser considerada bem interessante. Uma vez que se detêm conhecimento para criar testes que forcem defeitos, o entusiasmo é enorme. Mas atenção, a prioridade deve ser dada ao fluxo principal, primeiro crie testes para as situações em que se espera que o software funcione.

Alguns cenários são mais complexos de serem testados. Casos como atualização de estruturas de dados, modificação de certos recursos e chamadas da API que não possuem retorno, necessitam de alguma forma de verificação. Uma função que não tem retorno, por exemplo, deve mudar de alguma forma o estado da aplicação. Em um teste a uma chamada que remove algum valor de uma lista e não tem valor de retorno, pode ser necessário usar de chamadas para percorrer a lista e verificar os valores, tendo assim certeza de que o valor solicitado foi removido.

James Whittaker e Alan Jorgensen relataram que, em teste de API, alguns problemas interessantes para os testadores são: garantir que a aplicação varia os parâmetros das chamadas de modo a expor possíveis falhas; gerar combinações interessantes de parâmetros; configurar o ambiente externo e os dados internos que afetam a API; variar a seqüência de chamadas da API para exercitar de várias formas as funcionalidades.

No blog de testes da Google, em um dos posts é mencionado que testes de chamadas isoladas da API não conseguem simular o cenário real. Para uma calculadora, testar as chamadas isoladamente pode ser efetivo. Mas para aplicações em que a ordem das chamadas pode interferir no resultado, devem ser testadas tanto as chamadas isoladas como combinações entre elas.

A organização dos testes é importante para facilitar a manutenção. Códigos bem escritos podem auxiliar no entendimento da equipe sobre o que está sendo testado. Então, caso possível, o uso de um guia com padrões de codificação é bem vindo. Dessa forma, a equipe irá se acostumar a escrever de forma que todos entendam. Quando o cenário de teste é complexo, a documentação no código ajuda a entender do que se trata.

A qualidade do código de teste pode influenciar diretamente na qualidade do produto testado. Erros nos testes podem omitir falhas importantes nos produtos.

Mas quem vigia os vigilantes? Quem testa o código de teste? Como garantir que os testes estão corretos? Quando se escreve códigos de teste, a atenção deve ser dobrada. Com isso é importante a cultura de revisão de código, programação em pares ou alguma outra forma que auxilie na diminuição de erros. Criar log da execução pode ajudar na identificação de problemas.

Pelo fato de os testes serem parecidos, a prática do copy & paste vai parecer tentadora. Mas evitar esta prática pode evitar vários problemas. Recomendo uma apresentação de Borba, para ter a visão dele sobre código duplicado. E, se em algum momento achar que o código de teste pode melhorar, melhore!

Nos projetos que trabalhei, a padronização dos testes foi um ponto importante, para transferência de conhecimento aos que precisavam entender o que estava sendo testado. Para o emulador de J2ME, foi criado um framework no qual as aplicações de teste deveriam ser desenvolvidas. Em ambos os projetos, certos testes precisavam de uma confirmação visual, mas ainda assim foi possível avaliar tais cenários, só demandava uma confirmação do testador. Nos testes foram contempladas variações de parâmetros e combinações de chamadas. Também foram utilizadas algumas técnicas de teste como pairwise, classe de equivalência, valores limite, etc. Os testes eram documentados e tanto o documento como o código passavam por um processo de inspeção. Sempre que possível, os testes eram projetados para necessitarem da menor intervenção humana, realizando o maior número de testes ao apertar um único botão.

Nenhum comentário:

Postar um comentário