wicz journal

Everybody's worried about time, but I just keep that shit off my mind. 
« Back to blog

TDD em: O que testar?

Quando comecei a implantar desenvolvimento guiado por testes (TDD) na empresa em que trabalhava, tive a sorte de fazer parte de uma equipe de desenvolvedores bastante competente. Com apenas uma apresentação de poucos minutos e duas semanas de prática, quase todos já conseguiram captar que a essência do TDD não é apenas validação de código, mas também a especificação de determinada funcionalidade.

Tive apenas um caso em especial. Depois de algumas sessões de programação em par passei o teclado para o companheiro. Ele virou pra mim e disse: “Tá, e agora?”. Nós já tínhamos discutidos anteriomente o contexto da funcionalidade, mas mesmo assim ele estava repleto de dúvidas sobre o que realmente implementar

Para tentar esclarecer um pouco as dúvidas, fiz uma breve pesquisa na bibliografia e cheguei nos conceitos Right-BICEP e CORRECT.

  • Right – Are the results right?
Dados valores de entrada e seus respectivos valores de saída, verifica-se se a implementação esta de acordo, ou seja, se os resultados estão certos.
  • B – Are all the boundary conditions CORRECT?
Verificar se os valores estão dentro do domínio, dos limites aceitáveis. Por exemplo, uma validação de preenchimento de um campo, ou ainda se este foi preenchido na formatação adequada. Veja abaixo a descrição do acrônimo CORRECT, que descreve algumas condições de limites.
  • I – Can you check inverse relationships?
Alguns métodos podem ser verificados aplicando a sua lógica inversa. Por exemplo, para verificar o resultado de uma divisão, podemos comparar o dividendo com a multiplicação do divisor com o quociente, adicionado ao resto.
  • C – Can you cross-check results usings other means?
Semelhante a relação inversa, podemos verificar os resultados por outros meios. Podemos certificar o sucesso de uma inserção de uma elemento em um vetor, verificando se o tamanho deste antes da inserção e acrescido de um, é igual o tamanho depois da inserção (1 + Ni = Ni+1).
  • E – Can you force error conditions to happen?
Verificar como a aplicação se comporta em situações adversas. Podemos forçar um erro simples, com uma passagem de parâmetros incorreta, por exemplo. Mas não podemos esquecer dos outros diversos possíveis problemas do dia-a-dia. Uma falha na comunicação, espaço em disco que se acaba, memória insuficiente, etc. Uma maneira de testar isso é a utilização de objetos Mock?. Mas isso já é pano para outra manga =)
  • P – Are performance characteristics within bounds?
Nesse caso não queremos testar o desempenho em si, mas sim se a curva de desempenho se mantém estável, mesmo variando os cenários. Suponha que os testes de uma busca em um vetor de tamanho N passam em tempo t. E se agora o vetor for de tamanho N+M, os testes continuam passando em tempo t+m?

Como muitos dos problemas aparecem na verificação das entradas e saídas, é importante ter bem definido o seu domínio, ou limites (boundary). Felizmente temos mais uma ferramenta para nos ajudar nessa definição.

  • Conformance – Does the value conform to an expected format?
Verifica se o valor em questão esta de acordo com o formato estabelecido. Por exemplo, um CPF ou CNPJ, ou ainda uma estrutura mais complexa como uma árvore binária.
  • Ordering – Is the set of values ordered or unordered as appropriate?
Diz respeito a ordenação dos valores. Suponha os processos de uma cafeteira (bom exemplo!): colocarFiltro(), colocarPo(), colocarAgua(), servirCafe(). Esses processos necessariamente precisam estar nessa ordem, caso contrário ninguém vai conseguir beber o valor de saída.
  • Range – Is the value within reasonable minimum and maximum values?
Dado valor deve estar dentro do domínio. Por exemplo, o preenchimento do ano de nascimento em um formulário [1900,2007].
  • Reference – Does the code reference anything external that isn’t under direct control of the code itself?
Verificar se um cenário referencia ou depende de outro fora do seu escopo. Suponha um portal de compras. Antes de adicionar qualquer produto ao carrinho, o usuário deve ter iniciado uma sessão (efetuado login). Existem pré e pós-condições que devem ser satisfeitas para passar o teste.
  • Existence – Does the value exist (e.g., is non-null, nonzero, present in a set, etc.)?
O teste mais intuitivo, acho. Verificar e um determinado valor de fato existe. Se certo parâmetro foi preenchido.
  • Cardinality – Are there exactly enough values?
Outro simples também. Se a cardinalidade, quantidade dos parâmetros passados é suficiente.
  • Time (absolute and relative) – Is everything happening in order? At the right time? In time?
Devemos verificar se execução de diversos processos em ordem. Cada um executando no momento certo. Lembra do exemplo da cafeteira? Também se aplica aqui. Eu disse que era um bom exemplo =). Você também pode imaginar uma linha de produção.

Acho que isso é um bom começo. Mas gostaria de deixar bem claro que isso não se trata de um guia, muito menos de uma receita de bolo. São apenas alguns lembretes para facilitar e aprimorar a implementação dos seus testes. Caso você tenha se interessado neste tópico e queira a versão in extenso, você DEVE ler Pragmatic Unit Testing in Java with JUnit.

Feliz TDD!

Loading mentions Retweet

Comments (1)

Mar 10, 2010
Altieres said...
Excelentes conceitos. Vou passar adiante para o pessoal da minha empresa! Precisamos nos atentar em aprender mais sobre TDD (e assuntos relacionados) a cada dia, só assim teremos uma suite de testes eficaz, do contrário escreveremos testes só pra dizer que temos teste.

Leave a comment...

 
Got an account with one of these? Login here, or just enter your comment below.
Posterous-login    twitter