38
Luiz Carlos d´Oleron [email protected] SJCP JUnit Java Avançado

Luiz Carlos d´Oleron [email protected] SJCP JUnit Java Avançado

Embed Size (px)

Citation preview

Page 1: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´[email protected]

SJCP

JUnit

Java Avançado

Page 2: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

O que é JUnit?• Que tipo de aplicações

eu posso fazer com JUnit?

• Para que serve JUnit?

• Como usar o JUnit?

Page 3: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

JUnit e testes

• JUnit é um framework para criação de testes

• Com JUnit não fazemos a aplicação em si, mas...

• Podemos criar código que irá testar código

• ...mas para quê?

Page 4: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Para que testar?• E por que não testar?

• Você sempre testa suas sistemas

• Seja com um método main

• Seja usando o sistema depois de uma implementação

• Testes aumentam a confiança no código

• Testes diminuem o medo de alterar o código

Page 5: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Por que testar?

• Para garantir que o código está funcionando

• Para validar requisitos

• Para validar modificações

• Para identificar erros

• Para simplificar o desenvolvimento

Page 6: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Por que testar?

Mais cedo ou mais tarde seu código será testado, mesmo que seja quando o cliente

estiver usando o sistema!

Page 7: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Por que JUnit?• Por que ele automatiza os testes

• Testes automatizados são essenciais no desenvolvimento atual

• Eles validam os requisitos do sistema

• Eles modelam os requisitos do sistema!

• Eles identificam os ERROS, mesmo quando você nem imagina que eles poderiam ocorrer!

Page 8: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Desenvolvimento Orientado a Testes

“Quanto mais velho eu fico, mais agressivo me torno em relação a testes. Testes deveria ser um processo contínuo. Nenhum código deveria ser escrito até que você saiba como testá-lo. Uma vez que você escreva um código, escreva os testes para ele. Até que os testes funcionem, você não pode anunciar que terminou de escrever o código.”

Martin Fowler, UML Essencial, 2ª Edição, Bookman

Page 9: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

O que é teste automatizado

• É uma aplicação que irá executar, a pedido do programador, ou de forma programada

• Normalmente quando o sistema está sendo desenvolvido

• Que irá testar o código do sistema

• Gerando uma resposta “sim” ou “não”

• Representando que o código passou ou não passou no teste

• É comum também um relatório descrevendo os erros ou falhas, quando elas ocorrem.

Page 10: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

O que é um teste de unidade?

• É um teste que irá avaliar uma unidade

• Uma unidade é uma parte lógica do código– Pode ser um objeto inteiro– Um método– Uma transição– Um estado

• Avalia somente o comportamento do componente

• Não avalia as interações do componente com outras entidades

Page 11: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

O que testar?• Situações de sucesso

– O método fornece o comportamento esperado quando recebe a entrada correta? Testes os cenários aonde tudo dá certo.

• Situações de falha– O método se comporta como esperado quando colocado sob condições

“hostis”? Testes os cenários aonde tudo dá errado.

• As pré-condições– Como o sistema deve estar antes da execução do método?

• As pós-condições– Como o sistema deve estar após a execução do método?

• Teste (principalmente) as regras de negócio– GUI´s e código de formatação pode ou não pode ser testado

Page 12: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

JUnitJUnit é um framework para testes de

unidades automatizados para aplicações Java. Todo tipo de aplicação (web, desktop, mobile) poderá se beneficiar de JUnit.

Foi criado por Erich Gamma (escritor de Design Patterns) e Kent Beck (criador da metodologia XP).

Page 13: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

JUnit

Existem plug-ins para praticamente todas as IDE´s sérias de desenvolvimento Java. Lembre-se que você poderá usar JUnit mesmo se não estiver usando nenhuma IDE, compilando e executando tudo pela linha de comando. Além disso, JUnit se integra perfeitamente com a tecnologia ANT.

Usar JUnit é muito simples. basicamente utilizamos:

• TestCases• Fixtures• Test Suites

Page 14: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

JUnit

• TestCases– Um TestCase define uma fixture para ser avaliada perante um conjunto

de testes.– Cada classe deveria ter um TestCase associado– O normal é termos um TestCase que instancia um objeto e testa todos

os seus métodos

• Test Fixtures– Recursos necessários para a execução do teste– variáveis primitivas– Objetos

• Test Suite– Coleção de testCases correlacionados

Page 15: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Criando um teste• Criaremos um novo projeto no

Eclipse, normalmente, como fizemos antes

• Em libraries, podemos usar add External Jars... para definir o local de junit.jar

• Podemos também usar Add Variable... para indicar que utilizaremos JUNIT_HOME

• Eclipse possui um Wizard para criação de TestCases, mas, para facilitar nosso entendimento, não usaremos ele

Page 16: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Criando o TestCase• Criamos uma classe,

normalmente, chamando-a de TestHashMap

• Colocaremos ela no pacote testes

• Importante: Nossa classe deverá extender junit.framework.TestCase

• Marque a opção public static void main(String [] args)

• Clicamos em Finish

Page 17: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Codificando o teste• Eclipse criou para nós o

esqueleto de uma classe que extende TestCase

• Adicionamos 5 variáveis ao nosso teste. Estas variáveis são os fixtures do teste

• Elas nos ajudarão a testar a classe HashMap

•Observe que utilizamos generics para definir uma Map que mapeia Strings em Strings

•Se você não tiver configurado o projeto para usar Java 5.0, Eclipse e o compilador javac irão reclamar!

Page 18: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

setUp e tearDown

• Após adicionarmos nossos fixtures, vamos codificar os métodos protected void setUp() throws Exception e protected void tearDown() throws Exception

• Esses métodos são responsáveis por configurar os fixtures e liberar os recursos dos fixtures, respectivamente.

• Observe que setUp e tearDown são protected, eles já existem em TestCase, de forma que quando os codificamos, estamos realizando overriding

• No nosso exemplo, todos os recursos adquiridos por setUp serão coletados pelo Garbage Colector. Por isso, nosso método tearDown terá uma implementação vazia (não era necessário nem mesmo reescrevê-lo)

• Se setUp alocasse conexões de rede ou com banco de dados, era necessário que nós liberássemos esses recursos dentro de tearDown

Page 19: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

setUp e tearDown

• O eclipse possui um recurso para Override (Menu Source >> Override/Implements Methods) que poderá facilar a escrita de setUp e tearDown

• Se esse recurso for utilizado, observe que eclipse incluirá a annotation @Override

• setUp e tearDown serão executados antes e depois, respectivamente, de cada teste

Page 20: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Codificando os testes• JUnit utilza um padrão para a criação de testes

• Testes são métodos de subclasses de TestCase

• Todo teste deve possuir a assinatura:

public void testXXX()

• Aonde XXX pode ser trocado por outro identificador

• JUnit utilizará este padrão para encontrar os métodos que serão executados

• Normalmente, temos um teste para cada método do fixture

Page 21: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Codificando os testes

• Nos testes é onde nós manipulamos as fixtures e fazemos asserções sobre o comportamento delas

• No nosso exemplo, nós testaremos apenas dois métodos de Map, o size e o put

• Utilizamos duas versões do método assertEquals da classe TestCase. Existem outros tipos de asserções, como assertNull e assertNotNull

Page 22: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

TestRunner

Finalmente, escrevemos o corpo do método main, de forma que possamos chamar o TestRunner

Page 23: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

TestRunner• JUnit vem com três tipos de TestRunner:

– junit.swingui.TestRunner– junit.textui.TestRunner– junit.awtui.TestRunner

• Cada tipo utiliza uma tecnologia para executar e apresentar os resultados do teste

• Ao executar a classe TestHashMap, o testRunner escolhido irá ser invocado

• Eclipse vem com o próprio TestRunner, que pode ser executado clicando-se Run >> Run as >> JUnitTest

Page 24: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

junit.swingui.TestRunner

Page 25: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Eclipse e New JUnitTest Wizard

• Eclipse possui uma ferramenta para criação automática de TestCases

• Basicamente, o New JUnitTest Case Wizard cria uma subclasse de TestCase

• Para cada método e contrutor, o New JUnitTest Case Wizard cria um método testXXX

• O corpo dos testes está inicialmente vazio, ficando a cargo do programador codificar os testes.

Page 26: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Eclipse e New JUnitTest Wizard

Page 27: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Test Suite

• As aplicações são compostas de dezenas, centenas ou milhares de classes

• É comum que em um projeto existam um número enorme de TestCases

• Test Suite é uma forma de agrupar Test Cases correlatos. Ao invés de executar os testes um por um, com Test Suite é possível executar todos os testes de uma vez.

• Mais uma vez, Eclipse possui um Wizard para criação de Test Suites

Page 28: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Test Suite

• Para criar um Test Suite, clique com o botão direito no pacote aonde os testes estão. Em seguida, clique em new >> other

• Expanda a pasta java e em seguida expanda a pasta JUnit

• Selecione JUnit Test Suite e Clique em Next

Page 29: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Test Suite• Se desejar, redefina o nome do

TestSuite

• Selecione os Test Cases e clique em Finish

• Se desejar, você poderá criar um método main que chamará um test runner específico

• Eclipse terá criado Test Suite para você

• Para executá-lo, clique em Run >> Run As>>JUnit Test

Page 30: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Aonde colocar os testes?

• O ideal é colocá-los no mesmo pacote das classes testadas

• Assim, será possível acessar os métodos e variáveis com visibilidade default-protected

• Ant-Scripts podem dividir as classes do sistema das classes de testes para deploy

• Colocar em uma hierarquia paralela também é uma estratégia utilizada

Page 31: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Limitações do JUnit

• Código testando código pode gerar problemas de “realimentação” (quem sabe se o código de testes está correto?)

• JUnit testa só características não privadas (só as acessíveis)

Page 32: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

TDD

• É possível usar JUnit sem aplicar TDD

• Mas o maior ganho de usar JUnit ocorre quando você usa TDD

• TDD – Test Driven Development– Desenvolvimento orientado a testes– Associado à técnicas de desenvolvimento ágil

Page 33: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

TDD

• Antes de codificar, crie um teste para o código

• O teste não irá compilar, muito menos executar

• Então, construa o “esqueleto” do código até que o teste compile

• Rode o teste, ele irá falhar

• Codifique até que o teste passe (sem mexer no teste)

• Não codifique mais, trabalho terminado!

Page 34: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

TDD

• Garante que todo código irá ser testado

• Permite que o código que será construído seja o mais simples possível

• Quando o programador for construir o código, ele saberá exatamente qual deverá ser o comportamento do dele

• TDD é utilizado com metodologias de desenvolvimento ágil - www.agilealliance.com

Page 35: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Refactoring• Uma técnica utilizada no desenvolvimento de software, em especial,

no desenvolvimento ágil de software, é o Refactoring.

“Refactoring is the process of rewriting a computer program or other material to improve its structure or readability, while explicitly keeping its meaning or behavior.”

http://wikipedia.org

• Como garantir que o comportamento do software será o mesmo após o refactoring?

• Como garantir que o refactoring não foi agressivo ao código, gerando erros?

• Para garantir Refactoring, é indispensável o uso de testes. O processo é realizado comparando as saídas dos testes realizados antes e depois do Refactoring.

• Sem testes, não existe Refactoring!

Page 36: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Mitos de testes

• Criar testes atrasam o desenvolvimento– Errado. Encontrar bugs é o que atrasa desenvolvimento

• Testes só no final– E o que fazer se todos os testes falharem?

• Se todos os testes passam, o sistema está perfeitamente a prova de falhas– Todas as possibilidades foram testadas?

• Testes só para testar– Testes são uma ferramenta importante para a especificação de

requisitos

Page 37: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Atividade prática• Criar a classe Autentica, que possui apenas o método:public boolean autenticar(String login, String senha)

• Este método deve verificar se o login e senha são válidos, retornando true. Se login e senha não conferirem, o método deve retornar false.

• Caso login ou senha sejam passados null ou igual à String vazia, autenticar deve lançar uma java.lang.IllegalArgumentException.

• Caso sejam efetuadas três tentativas inválidas seguidas, todas as tentativas seguidas devem falhar, indiferente do que for fornecido como login e senha

• Crie uma classe de testes para validar estes requisitos

• Você poderá criar tanto a classe primeiro ou o teste primeiro

• Escolha uma forma para que cada objeto da classe Autentica possa armazenar as combinações corretas de login e senha

Page 38: Luiz Carlos d´Oleron lcadb@cin.ufpe.br SJCP JUnit Java Avançado

Luiz Carlos d´Oleron – [email protected]

Bibliografia• Java Tools for Extremme Programming, Richard

Hightower

• Desenvolvimento guiado por testes com JUnit, Helder da Rocha

• Jakarta-Struts Live, Richard Hightower

• UML Essencial, Martin Fowler

• www.junit.org