Você está na página 1de 11

Implementando testes unitários em Java

O que são teste unitários?


O teste unitário é uma modalidade de testes que se concentra na verificação dos métodos do projeto
de software. É realizado o teste dos métodos, com uso de dados suficientes para se testar apenas à lógica do
mesmo.
A grande vantagem dos teste é que evitamos de ficar abrindo a tela do sistemas preenchendo com
dados e clicando em algum botão para saber se a rotina funciona. Além disso teremos o código com teste
automatizado garantindo a integridade do sistema.

Testes Unitários - Por quê?


• Previne contra o aparecimento de “BUG’S” oriundos de códigos mal escritos.
• Código testado é mais confiável.
• Permite alterações sem medo (coragem)
• Testa situações de sucesso e de falha.
• Resulta em outras práticas XP como: Código coletivo, refatoração, integração contínua.
• Serve como métrica do projeto (teste == requisitos)
• Gera e preserva um “conhecimento” sobre as regras de negócios do projeto.

Teste unitários englobam


Extreme Programming metodologia ágil de desenvolvimento com foco em agilidade de equipes e
qualidade de projetos, apoiada em valores como simplicidade, comunicação, feedback e coragem.

TDD - Test Driven Development o conceito de Desenvolvimento Guiado por Testes define que antes
de criarmos um código novo (classe), devemos escrever um teste (classe de test case) para ele.
Organização dos testes

Executados Diariamente
É sugerido que seja rodado os testes várias vezes ao dia (é fácil corrigir pequenos problemas do que
corrigir um “problemão” somente no final do projeto ou versão).

Teste Unitário - Quem faz?


Desenvolvedor (Projeta, escreve e roda).

Teste Unitário - O que testar?


• A principal regra para saber o que testar é: “Tenha criatividade para imaginar as possibilidades de
testes”.
• Regras de negócios de todo o sistema(todo os métodos de regra de negócios).
• Comece pelas mais simples e deixe os testes “complexos“ para o final.
• Use apenas dados suficientes (não teste 10 condições se três forem suficientes)
• Não carregue grande quantidade de dados para testar um simples valor de retorno.
• Não teste métodos triviais, tipo get e set. Onde não existam regras.
• No caso de um método set, só faça o teste caso haja validação de dados.
• Achou um bug? Não conserte sem antes escrever um teste que o pegue (se você não o fizer, ele volta
porque alguém pode mexer e causar o mesmo bug)!.
Planejando os 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.
• Popule dados respectivos a tarefa caso não os tenha para que seja possível criar o teste.
• Rode o JUnit e certifique-se que o teste falha.
• Refatoração constante de código até isolar o bloco a ser testado.
• 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.
• Todas as condições de regras de negócio estão sendo validadas.
• O teste está passando.
• Faça esses passos para toda a lista de tarefas.

Métodos antigos de testes

O que tem de errado?


• Uso indevido da classe main.
• Tem que ser executado manualmente classe por classe.
• Era executado apenas uma vez e esquecido no projeto se tornando código “lixo”.
• Não teríamos como saber quando o método calcular estiver falhando porque não é verificado
constantemente.
• Não receberiamos nenhuma informação de notificação de falha.
• Uso só System.out.println e condições para saber se passou.
• Não tem como ser automátizado.
• Não possui métodos automatizados de verificação de resultado das regras de negócio que está sendo
testada.
Método novo de testes

O que temos de errado?


Não temos nada de errado nesse novo método, ainda podemos simplificar o código para apenas uma linha
obtendo o resultado abaixo.

Neste momento com o teste automatizado e sendo verificado constantemente, seremos notificados
claramente quando o método calcular falhar. Uma notificação de falha nos avisará que a regra de negócio do
sistema foi quebrada.

Características de teste e desenvolvimento


• Antes de iniciar um teste verifique a possibilidade de escrever o teste e que ele esteja passando, após
isso realize a refatoração do código.
• Durante a implementação de testes em um bloco de código já existente, pode ser necessário refatorar
totalmente o código para que seja possível realizar a escrita do teste unitário.

Abaixo veremos um exemplo de método que “a primeira vista”pode ser escrito um teste sem
ser feito nenhuma alteração no mesmo.
• Não está dentro de uma classe de tela, está dentro da ExameUtil.
• Se encontra em uma classe que pode ser usada por todo o sistema.
• É um método publico.
• Todas as informações que o método precisa estão sendo passados por parâmetro.
• Não deveria ser estático mas nesse caso não há problema.
Mas será que ainda pode ser mesmo testado?
Observe ainda temos um sério problema dentro do “catch” de exceção se acontecer uma exceção
será emitida uma mensagem exibindo uma tela swing isso acarretaria um sério problema, a tela de swing
seria exibida e pararia a execução automatizada de testes, alguém teria que ir na maquina que é executado
os teste e clicar para fechar a tela para os testes darem continuidade.
Para isso devemos retirar o código de dentro do try catch e passar ele para uma classe de serviço ou
dao, a chamada a esse serviço ficaria dentro do try catch para não quebrarmos a integridade de menssagens
do sistema.
O novo método escrito no serviço deve lançar as exceções para cima para ser capturar por esse try
catch.

Extração do método para uma classe de serviço.


ExameUtil.class.

O método criado na classe de serviço.


RequisicaoService.class.

Agora temos o método separado do try catch que mostra a tela de erro de msg, podemos nesse momento
realizar o teste unitário da classe de serviço.
Abaixo segue um exemplo de método onde não é possível escrever um teste unitário sem antes refatorar o
mesmo.
• O lugar onde o mesmo se encontra é uma tela e não podemos instanciar nenhum objeto de tela em
um teste unitário.
• Ainda mais complicado porque é usado uma variável “examesExcluidos” que o método desconhece
pois é recebido de fora e instanciado em tela.
• É um método privado.
• Não pode ser reutilizado por outras partes do sistema.

Alterações necessárias para que o teste unitário do método possa ser realizado.
• Mover o método para uma classe de serviço compartilhada por todo o sistema.
• Alterar o método para publico.
• Colocar a variável “examesExcluidos” sendo recebida como parâmetro.

Benefícios após as mudanças realizadas.


• Temos um teste unitário para o método do sistema (o método pode ser testado).
• Qualquer mudança no código que quebre a regra seremos notificados.
• O método não está mais amarrado a tela.
• O método se encontra disponível para todo o sistema.
• Pode ser reutilizado por qualquer parte do sistema.
• Pode ser utilizado por sistemas externos.

Quando desenvolvemos orientado a testes deve-se mudar totalmente a forma de programar, outros
objetivos devem ser levado em consideração e outros são totalmente obrigatórios para a realização do
mesmo.
Para que a implementação de testes unitário seja um sucesso não podemos amarrar os testes a um
determinado banco de dados, deve-se poder rodar os testes em vários banco de dados diferentes sem que
nenhum falhe.
Ferramentas para testes.
Junit – Framework para rodar de forma automática todos os método criados e para realizar as validações de
regras de negócio estabelecidas pelo sistema.
Hibernate – Framework completo de persistencia com banco de dados, utilizaremos apenas para controle de
conexão com banco e caso seja necessário criação de CRUDS de validação no testes.
Dbunit – Framework que simula uma base de testes com dados que são persistidos apenas durante o
tempo que leva os testes para rodarem.
Spring – Framework completo que engloba tudo que necessita para desenvolver projetos web e desktop,
usaremos apenas o módulo de JDBC para criação de CRUDS de validação, pequenos recursos de testes,
injeção de dependência e gerência de conexão.

JUnit – O que é?
JUnit é um framework que facilita o desenvolvimento e execução de testes unitários em código Java.
Ele Fornece uma completa API (conjunto de classes) para construir os testes e Aplicações.
Como uso do junit é possível com apenas alguns cliques rodar todos os nossos testes presentes no sistema.

JUnit – Por que?


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

Classes de teste
As classes de teste em junit devem fazer apenas o que o nome da classe diz, por exemplo a classe
TesteNotaFiscal essa classe não deverá realizar teste fora desse escopo.
Métodos de teste junit.
• Não podem ser estáticos, obrigatoriamente.
• Devem ser públicos obrigatoriamente.
• Não deve retornar nada, devem ser void.
• Por padrão e as versões mais antigas estabelece que o nome do método comece com test seguido
do nome do método que condiz com o que irá ser testado.
• Sempre anotados com @Test que define a execução automatizada do método.
• Sempre devem ter pelo menos um método de verificação junit implantado.
• Um teste só eu realmente um teste se cobre as condições de validações e contém “Asserts”.
Exemplo de este unitário validando o insert, consulta e delete de nosso
ProcedenciaNaoConformidadeService.class

Ainda podemos realizar o teste em cima do update seguindo a mesmo ideia, vimos que nesse momento
qualquer alteração que estrague o crud desse service será pego pelo teste.

Anotações Junit
@Test – Executa o teste estabelece que está sendo testado uma regra de negocio importante para o sistema.
@Before – método anotados com essa anotação serão executados antes dos métodos anotados com @Test
@After - métodos anotados com
@Ignore – Métodos anotados serão ignorados e não serão executados.

@Repeat – Presente no spring framework estabelece quantas vezes o método ai ser executado em repetidas
vezes, usando em conjunto com o Junit.

Hibernate
Framework de persistência engloba vários módulos, vamos usa-lo para controlar automaticamente nossa
conexão e simplificar nossos CRUDS de validações, sem precisar controlar nada na mão.
Exemplo de select.
SQLQuery sql = InterfaceCrudTest.
createSQLQuery("select * from usuario where usr_codigo in(:id)");
sqlQuery.setParameterList("id", new Object[]{1,2});
List<Object[]> resultado = sqlQuery.list();

Dbunit
Framework que realizada vários trabalhos de exportação de dados em xml pra serem trabalhados com
Junit bem como a simulação de base de dados usando xml.
Caso precisamos de certo registro inserido em nossa base de dados para os testes funcionarem ele
ira injeta-los em nossa base de dados usando um xml que represente os dados, após a finalização dos testes
irá reveter todo o processo garantindo a integração da base de dados, visto que para um projeto de testes ter
sucesso devemos garantir a integridade de nossa base de dados.
Usando Dbunit podemos rodar nossos testes em vários banco de dados diferentes sem nenhuma
alteração.
Exemplo de estrutura simulando a base de dados.

Para geração teste XML vamos utilizar uma classe do nosso projeto ou temos também a utulização do jailer
um programa java free para geração de xml para teste unitarios.

Spring Frameworks
Framework com mais de 10 anos de produção mantido constantemente pela SpringSource sendo referencia
no mundo todo e usado em projeto a nível mundial.
Módulos do spring em constante atualização com versões recentes.
Hoje o spring conta com mais de 20 módulos passando por desktop, mobile, web, banco de dados, web
services, segurança e muitos outros.
• Spring boot.
• Spring framework (deste usaremos a injeção de dependência).
• Spring xd.
• Spring data (deste utilizaremos a facilidade do Spring JDBC).
• Spring integration.
• Spring batch.
• Spring security.
• Spring social.
• Spring amqp.
• Spring mobile.
• Spring for android.
• Spring web flow.
• Spring web services.
• Spring ldap.
• Grails.
• Grovy.
• Spring cloud.
• Spring scala.
• Spring roo.
• Spring blazeds integration.
• Spring loaded.
• Spring shell.
• Rest full.

Exemplo de query simples em spring jdbc.

int qtdeUsers = InterfaceCrudTest.


getJdbcTemplate().
queryForInt("select count(*) from usuario where usr_codigo in(?, ?)",
new Object[]{“admin”,”adimin2”});
Exemplo de insert.

Consultando e populando uma entidade ou bean.

Desafios propostos
• A cada tarefa realizada desenvolver ao menos um teste unitário, dentro de pouco tempo teremos uma
grande parte do sistemas sendo verificado com teste unitários.
• Criar um trabalho de refatoração e criação de teste unitários para classe fora do escopo de tarefas se
possível, existem classes que após a refatoração e criação de teste diminuem pela metade a
quantidade de linha de códigos.

Finalizamo por aqui nosso tutorial, vamos partir para conhecer a estrutura do projeto que será usado
para desenvolver os testes, “vamos por a mão na massa”.

Próximos passos a partir do momento que todos estiverem familiarizados com teste unitários.

Ferramentas de análise de cobertura de testes.


Cobertura de testes com Emma.
Quando desenvolvemos testes automatizados para uma aplicação é importante avaliar se eles estão
alcançando todas as partes do sistema. O Emma é uma ferramenta open source que ajuda nesta tarefa,
fazendo a análise da cobertura de testes de um projeto Java e gerando um relatório em formato texto
ou HTML. Esse relatório representa um feedback importante para os desenvolvedores, pois indica quais
áreas do projeto ainda não estão sendo cobertas por testes automatizados e portanto devem ser tratadas
prioritariamente.
http://desenvolvimentoagil.com.br/xp/praticas/tdd/emma

Ferramenta de monitoração e regras/métricas de software.


Analisa o código constantemente, mostrando todos os feitos do projeto, e também roda os testes
automaticamente em tem programado sem haver intervenção humana.
http://hudson-ci.org/
Leitura.

http://junit.org/

http://www.dextra.com.br/tutorial-ou-melhor-um-passo-a-passo-explicando-o-funcionamento-do-junit-2/

https://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/pdf/hibernate_reference.pdf

http://dbunit.sourceforge.net/howto.html

http://spring.io/projects

http://spring.io/docs

http://camilolopes.wordpress.com/2008/08/11/boas-praticas-com-refactoring/

http://camilolopes.wordpress.com/2008/08/11/boas-praticas-com-refactoring/

http://camilolopes.wordpress.com/2008/08/18/serie-2-refactoring-vantagensdesvantagens/

http://camilolopes.wordpress.com/2008/08/25/serie-3-refactoring-e-manutencao-de-software/

Você também pode gostar