Whats new? | Login | Parceiros
Cadastre-se | Atendimento | RSS
+ Java:
artigos   |   vídeos   |    cursos   |    mais

Criando Testes de Unidades com o Junit 4 usando anotações

Neste artigo será feita uma abordagem sobre a versão do framework mais famoso para testes de unidade em plataforma Java e as novidades encontradas na sua versão 4.

RAFAEL SOTO
Rafael Soto (rafael.soto@gmail.com) é Bacharel em Ciência da Computação pela Universidade Salvador - UNIFACS, em 2005. Atualmente fazendo especialização na area de Aplicações Web e Comoponentes Distribuidos - Faculdade Ruy Barbosa. Tendo como experi...


Ver space do autor


Estatísticas:
Visualizações:
10230
Favoritado:
 7 vez(es)
Conteúdo:
Didática:
Utilidade:
1 0
votos: 2

Serviços:



Criando Testes de Unidades com o Junit 4 usando anotações

No presente artigo irei fazer uma abordagem sobre a versão do framework mais famoso para testes de unidade em plataforma Java e as novidades encontradas na sua versão 4. Ressalto que não irei entrar nos méritos de explicação do JUnit visto que o mesmo já se encontra presente em diversos artigos publicados no Portal Java Magazine.

JUnit se tornou de fato um padrão de framework para testes de unidades automatizados em plataforma Java. A versão inicial do framework contemplava uma série de recursos para a implementação de testes de unidade de forma fácil e flexível. A versão 4 é considerada uma das mais significativas atualizações por ter como principal proposta a simplificação da elaboração das classes de testes explorando os recursos de anotação presente na JDK 1.5 do Java. O framework agora suporta generics, enumerations, import estático e anotações – adição de metadados no código para reduzir a complexidade de implementação e aumentar consideravelmente o nível de reuso do código.

Mudanças nos Métodos de Teste
Nas versões anteriores do Junit todas as classes de teste eram escritas seguindo uma especificação que definia nomenclatura de nomes e operações para o algoritmo de teste. Utilizando reflexão o framework localizava todos os métodos de testes e os processava, como no trecho de abaixo.

import junit.framework.TestCase;
public class TesteUnidade extends TestCase {
  private int x = 1;
  private int y = 1;
  
  public void testMetodo() {
    int z = x + y;
    assertEquals(2, z);
  }

}
Listagem 1 – Exemplo de código da versão anterior do JUnit.

Em contraste, no JUnit 4 os métodos de teste são identificados com a anotação @Test. Observe que agora não é preciso iniciar os métodos de teste com a palavra test o que garante que os teste se aproximem mais dos nomes de métodos implementados como apresentado no código abaixo.

import org.junit.Test;
import junit.framework.TestCase;
 
public class TesteUnidade extends TestCase {
  private int x = 1;
  private int y = 1;
  
  @Test public void metodo() {
    int z = x + y;
    assertEquals(2, z);
  }

}
Listagem 2 – Exemplo de código JUnit 4.

Com o novo recurso é possível deixar os nomes dos métodos das classes de teste similares aos métodos reais gerando uma padronização de nomes. Por exemplo, Pessoa.getNome() é testado por PessoaTeste.getNome(); Lista.addAll() é testado por  ListTest.addAll().

A classe TestCase não foi descontinuada para garantir compatibilidade reversa com as outras versões embora não seja necessário a sua utilização. Com os recursos de import estático do java é possível escrever uma classe de teste sem estender da classe TestCase e a mesma permanecer com o mesmo formato como no exemplo abaixo

import static org.junit.Assert.assertEquals;
public class TesteUnidade {
  private int x = 1;
  private int y = 1;
  @Test public void metodo() {
    int z = x + y;
    assertEquals(2, z);
  }

}
Listagem 3 – Exemplo de código JUnit 4 sem estender de TestCase

Setup e TearDown
Na versão anterior do JUnit, existiam 2 métodos que eram utilizados para configurar o ambiente de teste antes e depois da execução de cada caso. O JUnit 4 substituiu os métodos por duas anotações @Before @After as duas respectivamente substituem os métodos setUp() e tearDown(). Qual a diferença?? A diferença é que agora ganhamos uma flexibilidade maior para definirmos os nomes dos métodos de inicialização da unidade de teste visto que o framework agora faz interpretações a partir das anotações.

Abaixo segue um exemplo comparativo de um método setUp() feito na versão anterior do JUnit (Listagem 4) e usando anotação na versão 4 do framework (Listagem 5). 

protected void setUp() {       
    System.setErr(new PrintStream(new ByteArrayOutputStream()));     
    inputDir = new File("data");
    inputDir = new File(inputDir, "xslt");
    inputDir = new File(inputDir, "input");       

}
Listagem 4 – Exemplo de código JUnit 3 ou anterior utilizando setUp()

@Before protected void inicializa() {    
    System.setErr(new PrintStream(new ByteArrayOutputStream()));      
    inputDir = new File("data");
    inputDir = new File(inputDir, "xslt");
    inputDir = new File(inputDir, "input");    

}
Listagem 5 – Exemplo de código JUnit 4 usando anotação

Uma grande observação a ser feita e é destaque nessa nova versão do JUnit são os nomes dados as anotações o que torna o processo de elaboração das classes de teste mais intuitiva e clean.

Note que utilizando anotações @Before, você pode criar múltiplos métodos de teste que serão executados antes de cada método de teste definido na classe.

O antigo método tearDown() segue a mesma regra podendo ser utilizado em múltiplos métodos para finalização de teste.

protected void tearDown() {
  doc = null;
  System.gc();   

}
Listagem 6 – Exemplo de código JUnit 3 ou anterior utilizando tearDown()

@After protected void finalizaDocumento() {
  doc = null;
  System.gc();   

}
Listagem 7 – Exemplo de código JUnit 4 usando anotação 

Para classes de teste que possuam superclasses não é mais necessário explicitar as chamadas de métodos setUp() e tearDown() nas superclasses. O framework se encarrega de chamar os métodos para você de forma automática se necessário. Métodos com anotações @Before na superclasse são chamados antes dos métodos @Before na subclasse. Métodos @After são chamados de forma inversa, primeiro os da subclasse e depois os da superclasse. 

Suíte-wide initialization
O JUnit 4 acrescentou uma nova funcionalidade que executada instruções antes da classe de teste e logo após a sua execução: @BeforeClass e @AfterClass.

private PrintStream systemErr;   
@BeforeClass protected void redirectStderr() {
    systemErr = System.err; // Hold on to the original value
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
}    
@AfterClass protected void tearDown() {
    // restore the original value
    System.setErr(systemErr);

}
Listagem 8 – Exemplo de anotações suite-wide. 

Imagine que você precisa salvar informações numa tabela do seu banco de dados em tempo de execução das suas classes de teste. A abertura e fechamento de conexões é um processo custoso e que ficaria inviável estar re-criando essa estrutura de dados a cada método de teste. Logo com as anotações @BeforeClass e @AfterClass é possível realizar os testes e garantir que as instruções de conexão e desconexão com o banco de dados seja realizada apenas uma vez.

Exceções no teste
Teste de exceções foi uma das maiores melhoras implementadas pelo JUnit 4. O antigo estilo de testar as exceções exigia que fosse implementado um bloco try/catch em volta do método que lança a exceção e dentro do bloco catch um método para validar a exceção.

public void testDivisaoPorZero() {    
    try {
        int n = 2 / 0;
        fail("Divisão por zero!");
    }
    catch (ArithmeticException success) {
        assertNotNull(success.getMessage());
    } 

}
Listagem 9 – Exemplo de anotações suite-wide. 

Era necessário saber no código de teste qual seria a instrução que iria levantar a exceção a ser testada e logo após colocar uma chamada para o método fail() que indica que o teste falhou.

O JUnit 4 trouxe de uma forma simples e elegante uma anotação na qual é informada a exceção esperada em um dado método de teste e se a exceção não for levantada ou ainda que levantada não seja a esperada o teste é tido como falho. 

@Test(expected=ArithmeticException.class) 
  public void divideByZero() {
    int n = 2 / 0;

}
Listagem 10 – Exemplo de anotações exception expected.

Caso no teste seja necessário validar se a mensagem de erro está coerente com o teste é possível incluir o bloco try/catch e realizar a verificação desse tipo de rotina. 

Ignorando testes
Quando se é necessário desativar ou ignorar na classe de teste algum método utilizamos a anotação @Ignore para substituir a anotação @Test assim não é preciso excluir ou comentar o código dos testes ignorados.

@Test(expected=ArithmeticException.class) 
  public void divideByZero() {
    int n = 2 / 0;

}
Listagem 11 – Ignorando um teste. 

Testes temporizados 
Com o JUnit 4 é possível inserir parâmetros de timeout para o teste e definir um tempo tolerável de execução do mesmo, caso o tempo estoure o teste é considerado falho. 

Esta anotação auxilia testes que contenham dentro de sua estrutura instruções bloqueantes como comandos de socket e acesso a banco de dados, por exemplo.

@Test(timeout=500) public void selectAllElements() {
    doc.query("select * from elements");

}
Listagem 12 –  Anotação para testes temporizados.

Novas assertions
No framework JUnit 4 foram adicionadas 2 tipos diferente de métodos assert() para a comparação de arrays.

public static void assertEquals(Object[] expected, Object[] actual)
public static void assertEquals(String message, Object[] expected, 

Object[] actual)
Listagem 13 –  Acerts de comparação de arrays. 

Considerações Finais
A versão 4 do JUnit não pode ser considerada uma versão de atualização do anterior e sim um novo framework. Embora simples e dinâmico o JUnit 4 deixa a desejar em alguns aspectos os quais são implementados pela versão anterior do Framework como a distinção entre uma falha (erros antecipados verificado por métodos assert()) e erros (erros não antecipados indicados por exceções). Outro ponto negativo do novo framework é a retirada do método suíte() que permitia a execução de múltiplas classes de teste.

No próximo artigo irei apresentar de forma prática como instalar e executar classes de testes no Eclipse IDE e irei comentar alguns exemplos de padrões de classe de teste.

Bons estudos e até a próxima...





Participe! Inclua um comentário
[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.


Marco Rojo
27/3/2007 09:04
Suite Bom dia, a nova maneira de executar multiplas classes de testes e atraves das anotacoes @RunWith e @Suite.SuiteClasses. Como no exemplo abaixo: import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ // classes de teste MeuTest1.class, MeuTest2.class }) public class SuiteFacadeTest { } Abracos, Marco Rojo.

[responder]

 
lex
19/9/2007 07:21
RE:   @RunWith(Suite.class) @SuiteClasses({edsac.turbina.model.ProductTest.class}) public class TurbinaTestSuite { public static Test suite() { return new JUnit4TestAdapter(TurbinaTestSuite.class); } }

[responder]
 
Alfredo Oliveira
24/9/2007 11:21
Múltiplos Métodos @Before e @BeforeClass Caro Rafael Escutei falar que em minha classe de teste posso ter vários métodos @Before e @After. Testei e vi que realmente posso. Mas qual seria a utilidade disso?

[responder]

 



 
 

[Este post ainda não foi associado a uma sequência]


[Fechar]
Este post está disponível para assinantes da Java Magazine ou para quem possui Créditos DevMedia.

  Conheça os planos de créditos DevMedia e visualize esse post agora mesmo!

Plano conveniência – Neste plano este post custa R$ 0,00 (Compre agora)
Esse plano permite que você compre somente um post, pagando por ele seu preço sem desconto.

Plano ocasional: Aqui este post custa: R$ -1,00 (assinante) ou R$ -1,00 (não-assinante)
Este plano é ideal para quem tem interesse em mais de um post. Você compra um mínimo de R$ 50,00 em créditos e ganha, em média, 50% de desconto no preço do post. Compre Créditos agora!

Assinatura de Créditos (Plano econômico) – Aqui este post custa R$ -1,00
Este plano é ideal para quem tem interesse em muitos posts. Com esse plano você compra R$ 180,00 em créditos e ganha, em média, 80% de desconto no preço do post. Assine este plano agora!

> Saiba mais sobre o Sistema de Créditos DevMedia
DevMedia Group   www.devmedia.com.br   |   www.javafree.org   |   www.mrbool.com
2010 - Todos os Direitos Reservados a DevMedia Group - (21) 3382-5038