Countdown

Final Countdown

Faltam dias. Ou segundos.

quarta-feira, 20 de maio de 2015

#20) Junit, uma ferramenta para testes

Olá!

Junit é uma framework com suporte à criação de testes unitários automatizados para a linguagem Java. Antes de introduzi-lo, vamos mostrar o conceito de Testes unitários e a sua relevância:

Teste unitário é uma modalidade de teste que tem como objetivo testar pequenos componentes do projeto, as suas unidades lógicas básicas.

Desta forma, há uma série de vantagens, tais como:

  • Prevenção de BUG's no projeto, indicando erros a serem corrigidos.
  • Maior confiabilidade no código, sempre colocado à prova.
  • Serve como um requisito de projeto, a ser cumprido.
  • Prevenção de grandes erros em um projeto que nunca foi testado, evitando o dispêndio de tempo para se encontrar onde se localizam os erros do software.

O ideal é implementar uma bancada de testes para cada tarefa do projeto, de modo que os testes possam ser realizados juntamente com o processo de codificação.

mpjuiiujfig02.jpg
Processo de testes unitários em um projeto.


Inicializando o Junit

Para utilizar essa ferramenta, é necessário baixar o plugin do Junit para a IDE utilizada (Netbeans / Eclipse). No caso do Netbeans, podemos baixar diretamente da própria IDE, conforme o procedimento abaixo:

Primeiro, vamos decidir para qual classe desejamos criar a bancada de testes. Em seguida, acessamos em Ferramentas a opção "Criar/ Atualizar Testes", usando o Junit.



Caso a framework não tenha sido instalada, uma janela de instalação será aberta. Depois de devidamente instalada, uma nova classe de testes terá sido criada:


Observe que o código é aberto (permitindo sua modificação) e é gerado automaticamente, economizando bastante tempo de codificação.

Na classe criada, temos um método especial específico para realizar os testes:

assertEquals(expResult, result, delta);

Em que expResult é o resultado esperado para o retorno da classe, result é o resultado obtido pelo retorno da classe e delta é a tolerância para o teste de igualdade.

O método para o teste tem a seguinte estrutura básica:

    @Test
    public void testRaiz() {
        Bhaskara B = new Bhaskara();
        float raiz = B.raiz(1,2,1);
        assertEquals(-1.0, raiz , 0.1);
        System.out.println("raiz = "+raiz);
    }

Agora basta testar o arquivo:



O resultado te informa a porcentagem de testes corretos e o tempo de execução total, resultados extremamente interessantes e úteis para um projeto, permitindo otimizar o código e corrigir eventuais bugs no mesmo:



Podemos criar múltiplas funções de teste e depois testá-las simultaneamente:

Lembrando que nossa função de extrair a raiz a partir da fórmula de Bháskara só contabiliza uma raiz, de modo que o resultado do testRaiz3() deverá ser falho:


É possível ver exatamente qual teste falhou e a linha de código que gerou aquele resultado falho, de modo a facilitar que o programador encontre o erro lógico de seu código e o corrija o quanto antes:



Métodos de teste do Junit

Temos vários métodos de teste da framework Junit. Abaixo, indicamos alguns principais:

  1. assertEquals (a, b, delta);  // Verifica a igualdade a = b com tolerância delta ( b - delta < a < b + delta).
  2. assertTrue( a>b );  assertFalse( a==0 ); // Verifica uma dada condição.
  3. public void DISABLED_teste() {...}   // Desativa um determinado teste.
  4. // Testes de pertinência para um ArrayList:

  // Nossa classe
   public void adicionarPalavra(){
        palavras.add("palavra");
    }
   // Classe de testes
    public void testAdicionarPalavra(){
        operacao.adicionarPalavra();
        assertTrue(NewClass.palavras.contain("palavras"));
    }


Um último recurso que trago como bônus é o requisito de teste usando um tempo limite de execução, indicando falha caso o teste demore um tempo superior ao desejado. Abaixo, temos a implementação deste método usando Threads, como já explicado em posts passados deste blog:

    /**
     * Test of raiz method, of class Bhaskara.
     */
    @Test
    public void testRaiz() throws InterruptedException 
    {
        Thread testThread = new Thread(){
            public void run(){
                raiz = B.raiz(1, 2, 1);
            }
        };
        
        testThread.start();
        Thread.sleep((long) 1); // Tempo desejado
        testThread.interrupt();
        
        if (testThread.isInterrupted())
            fail ("demorado demais");
        
        assertEquals(-1.0, B.raiz(1, 2, 1) , 0.1);
    }

Apenas para esclarecer as notações do Junit (especialmente do código padrão gerado assim que criamos um novo pacote de testes), vou deixar um pequeno glossário abaixo, retirado de uma das referências no final deste post:

Como demonstrado neste tutorial, um dos principais aprimoramentos no JUnit4 é o seu suporte para anotações. No JUnit 4 você agora pode usar anotações para fazer o seguinte:
  • Identificar um teste usando a anotação @Test ao invés de uma convenção de nomeação
  • Identificar os métodos setUp e tearDown com as anotações @Before e @After
  • Identificar os métodos setUp e tearDown que se aplicam à toda a classe de teste. Métodos anotados com @BeforeClass são executados somente uma vez, antes que quaisquer métodos de teste na classe sejam executados. Métodos anotados com @AfterClass também são executados somente uma vez, após todos os métodos de teste serem finalizados.
  • Identificar exceções esperadas
  • Identificar testes que deveriam ser ignorados usando a anotação @Ignore
  • Especificar um parâmetro de time-out para um teste

Assim concluímos o estudo da framework Junit, de modo que agora estamos aptos a testar futuros projetos que vamos desenvolver no futuro.


Referências:
http://www.devmedia.com.br/junit-implementando-testes-unitarios-em-java-parte-i/1432
http://pt.slideshare.net/JudsonMeloBandeira/junit-uma-ferramenta-para-testes-passo-a-passo
https://netbeans.org/kb/docs/java/junit-intro_pt_BR.html

Nenhum comentário:

Postar um comentário