Usando o JUnit

Pagina oficial: http://junit.org/
Git: https://github.com/junit-team/junit

Junit é um framework simples para escrever testes repetíveis automatizados com suporte na linguagem de programação Java. Com o Junit podemos criar testes para verificar funcionalidades de classes e seus métodos. Podemos automatizar também a execução de todos os testes de forma que quando for criada uma nova versão estável do sistema o framework execute todos os testes para garantir a integridade e estabilidade do sistema desenvolvido.

O Junit trabalha basicamente com anotações (Annotations). Essas anotações indicam se um método é de teste ou não, se um método deve ser executado antes da classe e/ou depois da classe, as anotações indicam também se o teste deve ou não ser ignorado e se a classe em questão é uma suite de teste, ou seja, se a partir desta classe é disparada a execução das demais classes de teste, entre outras anotações menos utilizadas.

Por que usar JUnit?

Os principais motivos que favorecem o uso desse framework são:

  • JUnit pode verificar se cada unidade de código funciona da forma esperada;
  • Facilita a criação, execução automática de testes e a apresentação dos resultados;
  • É Orientado a Objeto;
  • É free e pode ser baixado em: www.junit.org

Planejando os testes no JUnit

Metodologias ágeis como Extreme Programming, exigem organização e disciplina, portanto é sugerido que você faça um bom planejamento antes de sair por aí escrevendo código feito um doido.

A lista abaixo exemplifica bem como você pode planejar e executar seus testes:

  • Defina uma lista de tarefas a implementar (o que testar);
  • Escreva uma classe (test case) e implemente um método de teste para uma tarefa da lista;
  • Rode o JUnit e certifique-se que o teste falha;
  • Implemente o código mais simples que rode o teste;
  • Refatore o código para remover a duplicação de dados;
  • Caso necessário, escreva mais um teste ou refine o existente;
  • Faça esses passos para toda a lista de tarefas;

Arquitetura das classes no JUnit

Para uma melhor compreensão de como o JUnit funciona é importante que entenda como suas classes estão organizadas dentro da API do framework

Analisando o resultado no JUnit

Quando os testes forem executados em modo gráfico, Veja que os métodos testados podem apresentar os seguintes resultados:

  • verde para sucesso,
  • roxo para falha
  • vermelho para exceção.

Anotações

Para determinar se um método é de teste utilizamos logo acima da classe de teste a anotação: @Test

@Test
public void testName() {
}

Para ignorar um método de teste utilizamos a anotação: @Ignore

@Ignore
@Test
public void testName() {
}

Para determinar que um método vai ser executado antes dos demais métodos da classe de teste utilizamos a anotação: @BeforeClass.

Essa funcionalidade serve para que possamos antes de uma classe de teste por exemplo iniciar a conexão com o banco de dados, inicializar variaveis entre outras possibilidades. Exemplo:

@BeforeClass
public void setup() {
    dataBase = new DataBase();
    dataBaseConnection.open();
    dataBase.populate();
    list_name = new ArrayList<>();
    index = 0;
}

Para determinar que um método vai ser executado depois dos demais métodos da classe de teste utilizamos a anotação: @AfterClass.

Essa funcionalidade serve para que possamos depois de uma classe de teste por exemplo fechar a conexão com o banco de dados, ajudar o garbage collection a limpar os dados ociosos entre outras possibilidades.

@AfterClass
public void close() {
    dataBase.drop();
    dataBaseConnection.close();
    dataBase = null;
    list_name = null;
    index = null;
}

Para determinar que um método vai ser executado antes de cada caso de teste utilizamos a anotação: @Before.

Essa funcionalidade serve por exemplo para que antes de um método possamos inicializar variaveis. Exemplo:

@Before
public void initialize() {
    list_name = new Calendar.getAllNames();
    index = 55;
}

Para determinar que um método vai ser executado depois de cada caso de teste utilizamos a anotação: @After.

Essa funcionalidade serve por exemplo para que antes de um método possamos finalizar variaveis. Exemplo:

@After
public void finalize() {
    list_name = calendar.getAllNames();
    index = current_index;
}

Com a última versão do Junit podemos também determinar que um teste tem um tempo máximo para ser executado. Por exemplo caso desejamos que nosso teste não demore mais que 500 mili segundos podemos realizar a seguinte anotação:

@Test(timeout = 500)
public void fastTestCase() {
    Assert.assertEquals(1500, calendar.getSize());
}

Por fim em nossa última anotação temos uma das mais importantes para testes unitários. Nesta anotação podemos verificar se o método está retornando uma exception. Essa funcionalidade é muito importante por exemplo para sabermos se o sistema está realmente tratando exceções e/ou validando erros internos. Exemplo:

@Test(expected=NullPointerException.class)
public void testException(int input) {
    int month = 4;
    Assert.assertNotNull(calendar.getAllDays(month));
}

Asserts

Os asserts determinam se uma condição de teste foi atendida ou não. Para ver os tipos de asserts bem como suas utilizações acesse: https://github.com/junit-team/junit/wiki/Assertions

Como double tem problemas de arredondamento, a versão mais nova do JUnit pede para você passar o "tamanho do erro aceitável". No caso, estamos passando 0.00001. Ou seja, a diferença entre o esperado e o calculado pode ser de até 0.00001, que o JUnit entenderá como erro normal de arredondamento.

Uma outra ferramenta importante é a criação de uma suite de testes, que nada mais é do que uma classe java onde todos os testes são iniciados. Nessa suite são descritas as classes de teste ou padrão das classes de teste para a sua execução. Uma suite de teste é basicamente uma classe que vai disparar a execução das demais classes de teste.

Abaixo exemplo de uma classe de suite de teste onde são descritos os testes a serem executados:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.Suite({
    TestLogin.class,
    TestLogout.class,
    TestCalendarNavigate.class,
    TestCalendarUpdate.class
})

public class CalendarTestSuite {
}

Na anotação @RunWith indica a suite de teste e na segunda anotação @Suite.Suite é onde indicamos as classes de teste que serão executadas. Neste caso acima as classes TestLogin.class, TestLogout.class, TestCalendarNavigate.class e TestCalendarUpdate.class.

Entretanto há outra forma de disparar a execução de todos os testes. Com a anotação @ClassnameFilters definimos os padrões das classes de teste. Todas as classes de teste que atendem a esses padrões serão executadas.

Abaixo temos o exemplo de uma classe de suite de teste onde definimos os padrões das classes de teste. Dessa forma todas as classes de teste que estiverem no padrão citado serão executadas.

import javax.naming.NamingException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters;
import org.junit.runner.RunWith;

@RunWith(Suite.class)
@ClassnameFilters({ ".*Test", ".*Teste" })
public class SuiteTest {

    @BeforeClass
        public static void setup() {
    }

    @AfterClass
    public static void close() {
    }
}

Como está descrito acima então com a anotação “@ClassnameFilters({ “.*Test”, “.*Teste” })” as classes de teste contendo em seus nomes “Test” e “Teste” serão executadas automaticamente.


Simulando comportamentos com Mock Objects

results matching ""

    No results matching ""