Escrevendo testes de unidade com JUnit

Conforme dito no artigo Fases de Testes de software, os testes de unidade são a base de toda a fase de testes de um sistema. Esse artigo tem o objetivo de demonstrar, através de um exemplo prático como escrever testes de unidade utilizando JUnit.

Problema

Para exemplificar como os testes unitários podem ajudar a verificação do funcionamento do nosso código, será utilizado um clássico problema da teoria dos jogos: O Dilema do Prisioneiro.

De maneira resumida, o julgamento de dois suspeitos de um mesmo crime se baseará na resposta de cada um deles. Cada suspeito pode optar por NEGAR o crime ou DELATAR o outro preso. Cada suspeito é interrogado individualmente e sem conhecimento da resposta do outro. Os resultados possíveis são os seguintes:

  • Os dois suspeitos negam o crime: os dois serão presos durante 1 ano.
  • Um suspeito nega e o outro opta pela delação: o suspeito que realizou a delação será solto enquanto o outro será condenado a 10 anos de prisão.
  • Os dois suspeitos optam pela delação do outro: os dois serão condenados a 5 anos de prisão.

Como visto, esse é um problema onde a cooperação trará o melhor resultado, se analisado em conjunto.

Código a ser Testado

package com.matera.blog;

public class DilemaDoPrisioneiro {

private int PENA_INOCENCIA = 0;
private int PENA_CONDENACAO_MUTUA = 5;
private int PENA_CONDENACAO_INDIVIDUAL = 10;
private int PENA_CONDENACAO_CUMPLICES = 1;

public enum Resposta {
NEGACAO, DELACAO
}

public int calculaPena(Resposta respostaPrisioneiroA, Resposta respostaPrisioneiroB) {

if (respostaPrisioneiroA == Resposta.DELACAO) {

if (respostaPrisioneiroB == Resposta.DELACAO) {
return PENA_CONDENACAO_MUTUA;
} else {
return PENA_INOCENCIA;
}

} else {

if (respostaPrisioneiroB == Resposta.DELACAO) {
return PENA_CONDENACAO_INDIVIDUAL;
} else {
return PENA_CONDENACAO_CUMPLICES;
}

}

}

}
Listagem 1 – Código a ser testado

Testes

Os testes serão escritos utilizando a biblioteca JUnit, versão 4.

Pré-Requisitos

  • Eclipse
  • JUnit e Dependências: vide [1]

Preparando o Teste

A classe que contém o código de teste será anotada com o intuito de indicar que a classe deve ser executada utilizando o Junit4:

@RunWith(JUnit4.class)
Listagem 2 – Anotação que indica a execução através do JUnit4

Casos de Teste

Os casos de teste são o coração de cada teste unitário, neles são implementadas toda a lógica necessária para verificar o resultado da execução. De maneira simplista, um teste se baseia em verificar se o resultado obtido é igual ao resultado esperado.

Cada método de teste deve ser anotado com a anotação @Test e não há restrição referente à nomenclatura:

@Test
public void metodoTeste() {
...
}
Listagem 3 – Exemplo de uso da anotação @Test

A classe Assert [2] contém os métodos mais comuns utilizados na escrita nos casos de teste: assertEquals, assertNotNull, assertNull e assim por diante. O método assertNotNull verifica se o objeto não é nulo, o método assertEquals verifica se o resultado obtido é igual ao esperado e assim por diante:

@Test
public void testCenario1() {

Resposta respostaSuspeitoA = Resposta.DELACAO;
Resposta respostaSuspeitoB = Resposta.DELACAO;

DilemaDoPrisioneiro dp = new DilemaDoPrisioneiro();
Assert.assertNotNull(dp);

int penaSuspeitoA = dp.calculaPena(respostaSuspeitoA, respostaSuspeitoB);
int penaSuspeitoB = dp.calculaPena(respostaSuspeitoB, respostaSuspeitoA);

Assert.assertEquals(5, penaSuspeitoA);
Assert.assertEquals(5, penaSuspeitoB);

}
Listagem 4 – Exemplo de método de testes utilizando Asserts

Conforme descrito no início do artigo, sempre que dois suspeitos optarem pela delação, ambos serão condenados a 5 anos de prisão, é essa verificação feita no exemplo acima.

Execução

Com a classe de testes pronta, basta executar a classe no Eclipse, que contém integração nativa com JUnit. Com a classe aberta, acesse o menu Run > Run As > JUnit Test, seus testes serão executados e será exibido  o resultado.

Conclusão

Testes unitários são tão complicados quanto as unidades a serem testadas, mas acrescentam uma camada de segurança importante à aplicação. Qualquer alteração que gere impacto no funcionamento previsto será percebida rapidamente, dando possibilidade ao desenvolvedor de tomar as ações necessárias: seja corrigir a implementação ou atualizar os testes.

Referências

[1] Getting Started – JUnit

[2] Assert

Links Externos

JUnit

Dilema do Prisioneiro

Por MARCO ANTONIO ROCHA

Pai, marido, nerd e programador (não necessariamente nessa ordem). Analista de Sistemas ancorado na MATERA desde 2008. Desenvolvedor Java na maior parte do tempo, fuçador em tempo integral.

Postado em: 28 de novembro de 2013

Confira outros artigos do nosso blog

REST não é JSON

21 de agosto de 2017

Bruno Sofiato

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

JavaScript 6: diferença entre var, let e const

09 de maio de 2017

Otávio Felipe do Prado

Deixe seu comentário