Testes de Unidade com JUnit
Upcoming SlideShare
Loading in...5
×
 

Testes de Unidade com JUnit

on

  • 3,969 views

 

Statistics

Views

Total Views
3,969
Views on SlideShare
3,944
Embed Views
25

Actions

Likes
1
Downloads
133
Comments
0

2 Embeds 25

http://www.slideshare.net 24
http://www.health.medicbd.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Testes de Unidade com JUnit Testes de Unidade com JUnit Presentation Transcript

  • Testes de Unidade com JUnit Introdução prática ao uso de JUnit para desenvolver testes unitários
  • JUnit ● Junit: framework para desenvolvimento e execução de testes de unidade em programas Java ● Define um modelo de programação para a criação de testes de unidade em classes Java ● Disponibiliza o TestRunner: aplicação em modo texto ou gráfico para execução de testes ● Podemos baixar o Junit em www.junit.org – O arquivo junit.jar deve estar no classpath do nosso projeto
  • Facilidades do JUnit ● Permite criação de testes unitários para métodos pertencentes a uma classe ● Permite a definição e execução de um conjunto de testes unitários – Suites de Teste ● Permite a execução de teste com relato de problemas ocorridos e onde especificamente ocorreram os erros
  • JUnit Passo a Passo ● 1º Passo) – Criar uma classe de teste para cada classe a ser testada – Exemplo: classe Aritmetica terá como classe de teste AritmeticaTest – A classe de Teste deve herdar da classe TestCase do framework JUnit
  • JUnit Passo a Passo ● 2º Passo) – criar métodos de teste para cada método (ou funcionalidade) a ser testado (cujos nomes devem começar com a palavra “test”) com tipo de retorno void. – Exemplo para a classe AritmeticaTest: public void testSoma() public void testSubtracao() public void testDivisao() public void testMultiplicacao()
  • JUnit Passo a Passo ● 3º Passo) – para cada método de teste definir seu comportamento: – invocação de métodos da classe do sistema a ser testada – avaliação do resultado dos métodos sendo testados usando os métodos assertEquals(), fail(), assertNull(), assertNotNull() do framework JUnit
  • JUnit Passo a Passo Método Descrição Teste passa se assertEquals(a,b) Compara dois a.equals(b) valores assertFalse(a) a == false Avalia uma assertTrue(a) expressão booleana a == true assertNotNull(a) a != null Compara uma assertNull(a) variável com nulo a == null assertNotSame(a,b) a == b Compara dois assertSame(a,b) objetos a != b fail() Causa uma falha no teste atual
  • JUnit Passo a Passo: Exemplo public class Aritmetica { public int soma(int op1, int op2) { return op1 + op2; } public int subtracao(int op1,int op2) { return op1 -op2; } public int multiplicacao(int op1, int op2) { return op1 * op2; } public int divisao(int op1, int op2) throws Exception { if (op2 == 0 ) { throw new Exception(quot;Divisao por zeroquot;); } else { return op1/op2; } } }
  • JUnit Passo a Passo: Exemplo import junit.framework.*; public class AritmeticaTest extends TestCase { public void testSoma() { Aritmetica operacoes = new Aritmetica(); this.assertEquals(4,operacoes.soma(3,1)); } public void testSubtracao(){ Aritmetica operacoes = new Aritmetica(); this.assertEquals(2, operacoes.subtracao(3,1)); } public void testDivisao() { Aritmetica operacoes = new Aritmetica(); try { operacoes.divisao(3,0); fail(quot;Deveria lançar Excecaoquot;); } catch (Exception e) { } } public void testMultiplicacao(){ Aritmetica operacoes = new Aritmetica(); this.assertEquals(3,operacoes.multiplicacao(3,1)); } }
  • JUnit Passo a Passo: Exemplo ● Como Executar o teste? – Direto na linha de comando: java junit.textui.TestRunner ContaTeste – Ou inserir os métodos abaixo na classe de teste public static Test suite(){ return new TestSuite(AritmeticaTest.class); } public static void main(String[] args){ junit.textui.TestRunner.run(suite()); } TestRunner chama suite() automaticamente e trata como testes (e executa) todos os métodos sem argumentos cujos nomes começarem com quot;testquot;
  • JUnit Passo a Passo: Exemplo ● Teste com erro ● Teste sem erro
  • Observações ● Caso necessário, pode-se definir configurações iniciais para serem executadas antes de cada método de teste usando o método setUp() – configuração de objetos comuns aos casos de teste – configuração de recursos comuns aos casos de teste – (exemplo: abertura de conexões de banco de dados, socket, etc) ● Para liberar recursos utilizados pelos métodos de teste pode-se usar o método tearDown() – Exemplos de recursos que podem ser liberados: streams, fechar conexões de banco de dados, apagar/mover arquivos de dados.
  • JUnit Passo a Passo public class Aritmetica { private int op1,op2; public void setOp1(int op1) { this.op1 = op1; } public void setOp2(int op2) { this.op2 = op2; } public int soma() { return op1 + op2; } public int subtracao() { return op1 -op2; } public int multiplicacao() { return op1 * op2; } public int divisao() throws Exception { if (op2 == 0 ) { throw new Exception(quot;Divisao por zeroquot;); } else { return op1/op2; } } }
  • JUnit Passo a Passo import junit.framework.*; public class AritmeticaTest extends TestCase { Aritmetica operacoes; Executa antes de cada public void setUp() { operacoes = new Aritmetica(); método de teste operacoes.setOp1(3); operacoes.setOp2(1); } public void testSoma() { this.assertEquals(4,operacoes.soma()); } public void testSubtracao(){ this.assertEquals(2, operacoes.subtracao()); } public void testDivisao() { try { this.assertEquals(3,operacoes.divisao()); } catch (Exception e) { } } public void testMultiplicacao(){ this.assertEquals(3,operacoes.multiplicacao()); } }
  • Execução JUnit ● Seqüência de execução do JUnit: – Cria uma instância da classe de teste para cada método de teste. (Exemplo: 4 testes, 4 instâncias). – O test case é instanciado para executar um método testXXX() de cada vez. ● As alterações que ele fizer ao estado do objeto não afetarão os demais testes ● Para cada instância: – Chama o método setUp(); – Chama o método de teste; – Chama o método tearDown();
  • Suites de Testes ● Quando falamos em teste automatizado, é comum querermos executar um conjunto de testes de uma única vez; ● Suites de testes representam um conjunto de testes que serão executados seqüencialmente; ● JUnit define a classe TestSuite que: – Permite incluir todos os métodos de teste de uma classe em um suite de teste; – Permite definir uma classe que inclui todos os suites de teste das classes do sistema.
  • TestSuite ● P ermite executar uma coleção de testes – Método addTest(TestS uite) adiciona um teste na lista ● P adrão de codificação: – retornar um TestS uite em cada test-case: public static TestSuite suite() { return new TestSuite(SuaClasseTest.class); } – criar uma classe AllTests que combina as suites: public class AllTests { public static Test suite() { TestSuite testSuite = new TestSuite(quot;Roda tudoquot;); testSuite.addTest(pacote.AllTests.suite()); testSuite.addTest(MinhaClasseTest.suite()); testSuite.addTest(SuaClasseTest.suite()); return testSuite; } }
  • Observações gerais ● Cada teste deve verificar um pedaço específico da funcionalidade ● Não combine testes não relacionados em um único método testXXX() ● Se o primeiro teste falhar os seguintes não serão executados
  • Testes com Objetos Mock ● Mocks – São objetos “de mentira” (substitutos) que permitem isolar classes de um sistema. Conta LinhaItem Item Item: Item nome:String quantidade: int preco: int adicionar(): void total(): int total(): int
  • Testes com Objetos Mock public class Conta { public class Item { private int total; private String nome; public void adiciona (LinhaItem private int preco; linhaItem) { total += linhaItem.total(); public void setNome(String nome) { } public int total() { this.nome = nome; return total; } } public void setPreco(int preco) { } this.preco = preco; } public class LinhaItem { } private Item item; private int quantidade; public LinhaItem(Item item, int quantidade) { this.item = item; this.quantidade = quantidade; } public int total() { return item.getPreco() * quantidade; } }
  • Testes com Objetos Mock import junit.framework.TestCase; public class ContaTeste extends TesteCase { Conta conta = new Conta(); Item lasanha = new Item(); lasanha.setNome(quot;Lasanha verdequot;); lasanha.setPreco(10); Item refrigerante = new Item(); refrigerante.setNome(quot;Guaranáquot;); refrigerante.setPreco(2); Item sorvete = new Item(); sorvete.setNome(quot;Sorvete de Chocolatequot;); sorvete.setPreco(4); Item cafe = new Item(); cafe.setNome(quot;Cafe Expressoquot;); cafe.setPreco(1); LinhaItem linhaLasanha = new LinhaItem(lasanha, 2); LinhaItem linhaRefri = new LinhaItem(refrigerante, 4); LinhaItem linhaSorvete = new LinhaItem(sorvete, 1); LinhaItem linhaCafe = new LinhaItem(cafe, 2); conta.adiciona(linhaLasanha); conta.adiciona(linhaRefri); conta.adiciona(linhaSorvete); conta.adiciona(linhaCafe); assertEquals(34. conta.total); } }
  • Testes com Objetos Mock ● Problemas da classe ContaTeste: – Método de teste maior e complexo; – O teste não é verdadeiramente um teste de unidade: ● Uma falha no teste pode ser causada por uma falha na classe Conta, na classe LinhaItem ou mesmo na classe Item. ● Solução: – Usar objetos mock – Elimina a dependência entre as classes (Conta e LinhaItem) – Ao testarmos, ao invés de usar a classe LinhaItem, usaremos uma classe que “finge” ser a ela.
  • Testes com Objetos Mock ● Como usar mock no exemplo? – Usaremos uma classe especial chamada de LinhaMock ● Essa classe já recebe no construtor o valor total de uma LinhaItem. – A classe LinhaItem passa a implementar uma interface, Linha, com um único método: total() – Esse método será utilizado pela classe Conta. public interface Linha{ int total(); }
  • Testes com Objetos Mock ● Nova classe de Teste: public class ContaTeste{ public void TestaTotalNota() { Conta conta = new Conta(); conta.adiciona(new LinhaMock(20)); conta.adiciona(new LinhaMock(8)); conta.adiciona(new LinhaMock(2)); conta.adiciona(new LinhaMock(1)); conta.adiciona(new LinhaMock(1)); assertEquals(32,conta.total()); } public static Test suite(){ return new TestSuite(ContaTeste.class); } }
  • Usando Easymock ● Nem sempre é simples escrever objetos mock. ● Ferramenta Easymock: APIs para gerar objetos mock. ● Como fazer para testar um servlet que implementa um mecanismo simplificado de login, recebendo dois parâmetros: login e senha. – Para obter parâmetros em um servlet usamos ● getParameter(“nomeParametro”) da interface HttpServletRequest
  • Usando Easymock ● Qual seria o problema? – A interface HttpServletRequest possui mais de 10 métodos e só estamos interessados no getParameter(). ● Criar um mock objeto para isso significa criar uma classe coma implementação desejada de getParameter() e uma implementação vazia ou mínima para todos os outros métodos. ● Solução: – Usar APIs para gerar e manipular objetos mock. – Ao invés de criarmos uma classe que implementa uma interface específica, deixamos que o EasyMock faça isso por nós. ● Não precisaremos criar um arquivo para nosso mock.
  • EasyMock ● O EasyMock pode ser obtido em: – easymock.org ● Basta extrair do download a biblioteca easymock.jar e colocá-la no classpath de seu projeto.
  • Passo a passo usando EasyMock ● 1º Passo) – Solicitamos a criação de um mock para um interface particular HttpServletRequest requestMock = createMock(HttpServletRequest.class); ● 2º Passo) – Criamos comportamentos específicos ● O mock objeto request irá esperar que alguma outra classe acesse o seu método getParameter() expect(requestMock.getParameter(“login”)). andReturn(“Marilia”); expect(requestMock.getParameter(“senha”)). andReturn(“cefet”);
  • Passo a passo usando EasyMock ● 3º Passo) – Precisamos informar ao mock que ele já não está mais sendo preparado, ou seja, é hora da ação. – Para isso usamos o método replay(); – A partir deste ponto o mock pode ser usado normalmente onde antes teria sido necessário utilizar um objeto real da aplicação. replay(requestMock); LoginServlet loginServlet = new LoginServlet(); assertTrue(loginServlet.loginValido(requestMock ());
  • Passo a passo usando EasyMock ● Observações: – Os métodos usados para programar mock ficam disponíveis para a classe de testes através de um import estático dos métodos da classe EasyMock. import static org.easymock.EasyMock.*; – É necessário usarmos java 5 ou superior
  • Passo a passo usando EasyMock import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream out = response.getOutputStream(); if(loginValido(request)) { out.println(quot;Bem-vindoquot;); } else { out.println(quot;Acesso negadoquot;); } } public boolean loginValido(HttpServletRequest request) { if(quot;Mariliaquot;.equals(request.getParameter(quot;loginquot;)) && quot;cefetquot;.equals(request.getParameter(quot;senhaquot;))) { return true; } return false; } }
  • Passo a passo usando EasyMock import javax.servlet.http.HttpServletRequest; import junit.framework.TestCase; import static org.easymock.EasyMock.*; public class LoginTeste extends TestCase { public void testeLoginComSucesso(){ HttpServletRequest requestMock = createMock(HttpServletRequest.class); expect(requestMock.getParameter(quot;loginquot;)).andReturn(quot;Mariliaquot;); expect(requestMock.getParameter(quot;senhaquot;)).andReturn(quot;cfetquot;); replay(requestMock); LoginServlet loginServlet = new LoginServlet(); assertTrue(loginServlet.loginValido(requestMock)); } }
  • Para maiores informações ● Junit: – http://junit.sourceforge.net/ ● EasyMock – http://www.easymock.org/EasyMock2_2_Docum entation.html