Artigo Java Magazine 50 - Testes Unitários Eficazes

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (0)  (1)

Artigo publicado pela Java Magazine 50.

Esse artigo faz parte da revista Java Magazine edição 50. Clique aqui para ler todos os artigos desta edição

Testes Unitários Eficazes

Projeto de testes, critérios de qualidade e boas práticas

 

Os testes hoje fazem parte da rotina de todo desenvolvedor, e a gama de ferramentas disponíveis para esse fim é imensa. Apesar disso, nem sempresão desenvolvidos da melhor forma possível, com tempo e esforço sendo gastos na criação de testes com pouco valor. Neste artigo apresentamos, através de um exemplo completo, os desafios com que se deparam os desenvolvedores durante a atividade de testes e indicamos como criar casos de teste mais eficazes. Apesar de o foco ser no teste de unidade, com auxílio do JUnit 4 e do Emma, os conceitos são válidos para todas as fases de testes.

 

Alguns conceitos básicos

Vamos começar relembrando alguns conceitos. Os testes de unidade são a primeira fase de testes do software, sendo normalmente executados pelo desenvolvedor. Essa fase é, sem dúvida, a mais conhecida e a que possui mais ferramentas de apoio (JUnit, TestNG, JMock etc.). Tais ferramen tas facilitam e automatizam a execução dos testes e a análise de resultados, mas em geral não contemplam uma atividade fundamental: o projeto dos casos de teste.

De forma resumida, podemos dizer que um caso de teste descreve o comportamento esperado do programa em teste sob circunstâncias controladas. É constituído, basicamente, por uma entrada conhecida e um resultado esperado1. A entrada pode ser um parâmetro, uma mensagem numa fila, ou qualquer dado que alimente a unidade em teste2. O resultado esperado, por sua vez, pode ser uma mensagem noconsole, um registro no banco de dados, a geração de uma exceção e assim por diante. Quando o caso de teste é executado e o resultado obtido corresponde exatamente ao esperado, diz-se que o caso de teste “passou”. Caso contrário, considera-se que o caso de teste “falhou”.

Sabemos que o principal objetivo dos testes de software é encontrar erros no programa. Mas quando isso não ocorre, vemo-nos diante de um dilema: o software realmente não possui defeitos, ou o teste executado não foi bom o suficiente para encontrar os defeitos existentes? E essa questão leva a outra: quando determinar que a atividade de testes pode ser finalizada e o software possui qualidade suficiente?

A eficácia dos casos de teste é, portanto, um fator determinante para comprovar a qualidade do software. Como veremos a seguir, existem técnicas e critérios de teste que podem ser utilizados para indicar quando o conjunto de testes elaborado possui qualidade suficiente.

 

Nota 1: Um caso de teste, é claro, ainda possui muitas outras informações como identificador, objetivo, pré-condições, dependências, ambiente de execução etc.

 

 

Nota 2: Unidade em teste (UUT Unit Under Test), como indica o nome, especifica o que está sendo testado (um método, uma classe etc.).

 

 

Um exemplo

Utilizaremos uma aplicação de exemplo para mostrar desafios existentes no teste de software e como contorná-los. O exemplo apresentado converte valores por extenso e sua especificação é descrita a seguir:

O software converte um valor monetário descrito sob o formato “9999,99” (uma string) em sua representação textual (extenso). A parte inteira (Reais) pode conter de zero a quatro dígitos; a parte decimal (centavos) é opcional, mas quando utilizada deve conter zero ou dois dígitos. Caso o valor não possua parte decimal, a parte decimal pode ser representada através de um único dígito zero.

A modelagem da aplicação é direta: a classe abstrata Extenso (Listagem 1) implementa o algoritmo que transforma valores numéricos em textos, através do método protected numeroExtenso(). Esse método suporta valores de 1 a 9999.

 

Listagem 1. Conversão de números em extenso (contendo defeitos)

 

package br.com.jm.extenso;

 

public abstract class Extenso {

 

private static String[] unidades = { “”, “um”, “dois”, “três”,

               “quatro”, “cinco”, “seis”, “sete”, “oito”, “nove” };

 

private static String[] dezenas1 = { “”, “onze”, “doze”, “treze”,

               “catorze”, “quinze”, “dezesseis”, “dezesete”, “dezoito”, “dezenove” };

 

private static String[] dezenas2 = { “”, “dez”, “vinte”, “trinta”,

              “quarenta”, “cinquenta”, “sessenta”, “setenta”, “oitenta”, “noventa” };

 

private static String[] centenas = { “”, “cem”, “duzentos”,

“trezentos”, “quatrocentos”, “quinhentos”, “seiscentos”,

             “setecentos”, “oitocentos”, “novecentos” };

 

private int[] particao;

private String[] texto;

 

public abstract String extenso(String valor)

    throws ValorInvalidoException;

 

protected boolean numeroValido(String numero) {

  boolean ok = true;

    if (numero.length() > 4) {

       ok = false;

        } else {

           if (!””.equals(numero)) {

                try {

                    Integer.parseInt(numero);

                     } catch (NumberFormatException e) {

                      ok = false;

"

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?