Palestra Testes Unidade Com JUnit

Preview:

DESCRIPTION

Palestra sobre técnicas e fases de testes, e informações sobre boas e más práticas comuns ao utilizar JUnit para testes de unidade.Explica também as principais anotações do framework JUnit, e a anotação disponibilizada na versão 4.7: @Rule

Citation preview

Testes de Unidade com JUnit

Robinson Castilho – JUGMScastilho@bacarin.com.br

http://www.jugms.com.br

Apresentação

● Robinson Castilho● Desenvolvedor C++ e Java desde 2001● Sun Certified Java Programmer● Sun Certified Web Component Developer● Fundador da Bacarin Software● Instrutor SENAC/MS● Coordenador do JUGMS

Certa vez fui convidado...

Certa vez fui convidado...

Pilotar novo modelode avião

Avião Moderno

Avião Moderno Bonito

Avião Moderno BonitoInovador

Avião Moderno BonitoInovador Econômico

?

?

?

?

Um detalhe: o avião nunca...

Um detalhe: o avião nunca...

TINHA SIDO TESTADO

Olha o Avião

Roubada?

Roubada?

SIM

Roubada?

SIM

Pense no mundo real

Pense no mundo real

Cliente recebe um software:

Pense no mundo real

Cliente recebe um software:

Moderno

Pense no mundo real

Cliente recebe um software:

Moderno

Inovador

Pense no mundo real

Cliente recebe um software:

Moderno

Inovador

Econômico

Pense no mundo real

Cliente recebe um software:

Moderno

Inovador

Econômico

Nunca foi testado

Roubada?

Roubada?

SIM

Teste seu software

Agenda

Agenda

● Importância dos testes

Agenda

● Importância dos testes● Técnicas e Fases de testes

Agenda

● Importância dos testes● Técnicas e Fases de testes● Testes de Unidade

Agenda

● Importância dos testes● Técnicas e Fases de testes● Testes de Unidade

– Ferramenta JUnit

Agenda

● Importância dos testes● Técnicas e Fases de testes● Testes de Unidade

– Ferramenta JUnit– Boas e más Práticas

Agenda

● Importância dos testes● Técnicas e Fases de testes● Testes de Unidade

– Ferramenta JUnit– Boas e más Práticas

● Tomar chopp :)

Dados não mentem

Dados não mentem

Erros existem:

Dados não mentem

Erros existem:

1/3 poderiam ser evitados

Dados não mentem

Erros existem:

1/3 poderiam ser evitados

50% são detectados em produção

Dados não mentem

Erros existem:

1/3 poderiam ser evitados

50% são detectados em produção

Prejuízo de US$ ~60 bilhões/ano Fonte: http://www.nist.gov/public_affairs/releases/n02-10.htm

Para que serve um teste?

Verificar que uma determinada entrada

produzSEMPRE

uma mesma saída

Como testar corretamente?

Caixa Preta

Caixa Preta

Não se preocupa com o Não se preocupa com o código fontecódigo fonte

Caixa Preta

Não se preocupa com o Não se preocupa com o código fontecódigo fonte

Saídas são coerentes com as Saídas são coerentes com as entradas?entradas?

Caixa Preta

Não se preocupa com o Não se preocupa com o código fontecódigo fonte

Saídas são coerentes com as Saídas são coerentes com as entradas?entradas?

Equipe testes (normalmente) Equipe testes (normalmente) é diferente da equipe é diferente da equipe

implementaçãoimplementação

Caixa Branca

Caixa Branca

Trabalha com o código fonteTrabalha com o código fonte

Caixa Branca

Trabalha com o código fonteTrabalha com o código fonteAvalia aspectos:Avalia aspectos:

Caixa Branca

Trabalha com o código fonteTrabalha com o código fonteAvalia aspectos:Avalia aspectos:● Teste de condiçãoTeste de condição● Teste de fluxo de dadosTeste de fluxo de dados● Teste de ciclosTeste de ciclos● Teste de caminho lógicoTeste de caminho lógico● Código nunca executado...Código nunca executado...

Fases: Fases: Testes de Unidade

Fases: Testes de UnidadeFases: Testes de Unidade

Fases: Testes de UnidadeFases: Testes de Unidade

Testa o códigoTesta o código

Fases: Testes de UnidadeFases: Testes de Unidade

Testa o códigoTesta o códigoPequenas unidadesPequenas unidades

Fases: Testes de UnidadeFases: Testes de Unidade

Testa o códigoTesta o códigoPequenas unidadesPequenas unidadesIndependentesIndependentes

Fases: Testes de UnidadeFases: Testes de Unidade

Testa o códigoTesta o códigoPequenas unidadesPequenas unidadesIndependentesIndependentes(sub-rotinas, trechos)(sub-rotinas, trechos)

Teste de IntegraçãoTeste de Integração

Teste de IntegraçãoTeste de Integração

Testa a integração internaTesta a integração internade um sistemade um sistema

Teste de IntegraçãoTeste de Integração

Testa a integração internaTesta a integração internade um sistemade um sistema

Verifica se as peças Verifica se as peças do do quebra-cabeçasquebra-cabeças

Estão encaixadasEstão encaixadas

Teste de Sistema

Teste de Sistema

Ponto de vista do cliente finalcliente final

Teste de Sistema

Ponto de vista do cliente finalcliente final

Teste de Sistema

Ponto de vista do cliente finalcliente final

SimularSimular ambiente que o cliente utilizarácliente utilizará

Teste de Aceitação

Teste de Aceitação

Aprovado ou não?

Teste de Aceitação

Aprovado ou não?

Teste de Aceitação

Aprovado ou não?

Grupo restritoGrupo restrito

usuários finaisusuários finais

simulam o usosimulam o uso

em produçãoem produção

Teste de Aceitação

Aprovado ou não?

Grupo restritoGrupo restrito

usuários finaisusuários finais

simulam o usosimulam o uso

em produçãoem produção

Determina se o sistema satisfaz os critérios estabelecidos

JUnit

JUnitautomatizar testes de unidade

JUnitautomatizar testes de unidade

Open Source

JUnitautomatizar testes de unidade

Open Source

Largamente Utilizado

JUnitautomatizar testes de unidade

Open Source

Largamente Utilizado

Criação rápida de testes

JUnitautomatizar testes de unidade

Open Source

Largamente Utilizado

Criação rápida de testes

Diminuir necessidade de depuração

JUnitautomatizar testes de unidade

Open Source

Largamente Utilizado

Criação rápida de testes

Diminuir necessidade de depuração

Integrável ao Eclipse, Netbeans, Maven...

Utilizando JUnit 4

public class OlaMundoTest {@Testpublic void testSoma() {

assertEquals(10, Calc.soma(7,3));}

}

Relatório no Eclipse

JUnit - Ciclo de vida

*DZone RefCardz

@TestInforma que é um método de testeAtributos: ● expected● timeout

@Before e @AfterMétodos executados antes e após um método de teste (setUp e tearDown)

@Before e @AfterMétodos executados antes e após um método de teste (setUp e tearDown)

@BeforeClass e @AfterClassMétodos executados

antes e após uma classe de teste

Novidades do JUnit 4.7

Novidades do JUnit 4.7Anotação: @Rule

Novidades do JUnit 4.7Anotação: @RuleRedefinir e adicionar comportamentos

Novidades do JUnit 4.7Anotação: @RuleRedefinir e adicionar comportamentosMecanismo de Meta-testes simples e claro

@Rule● TemporaryFolder: Permite criar pastas e

arquivos que serão automaticamente deletados após o teste

public static class HasTempFolder {@Rulepublic TemporaryFolder folder= new TemporaryFolder();@Testpublic void testUsingTempFolder() throws IOException {

File createdFile= folder.newFile("myfile.txt");File createdFolder= folder.newFolder("subfolder");// ...

}}

@Rule● ExternalResource: Classe base para Rules que

necessitam obter recursos externos (socket, conexão com SGBD, etc...)public static class UsesExternalResource {

Server myServer = new Server();@Rule public ExternalResource resource = new ExternalResource() {

@Overrideprotected void before() throws Throwable {

myServer.connect();}

@Overrideprotected void after() {

myServer.disconnect();};

};

@Test public void testFoo() {new Client().run(myServer);

}}

@Rule● ErrorCollector: Permite que a execução do teste

continue, coletando todos os erros ocorridos

● Veja mais em: http://www.junit.org/node/574

public static class UsesErrorCollectorTwice {@Rulepublic ErrorCollector collector= new ErrorCollector();@Test public void example() {

collector.addError(new Throwable("first thing went wrong"));collector.addError(new Throwable("second thing went wrong"));

}}

Boas práticas

Boas práticas

● Execute os testes frequentemente

Boas práticas

● Execute os testes frequentemente● Escreva um teste para o defeito

antes de corrigi-lo

Boas práticas

● Execute os testes frequentemente● Escreva um teste para o defeito

antes de corrigi-lo● Escreva testes, não logs para depuração:

– System.out.println(...)– logger.info(...)

Más práticas

● Múltiplos assertions. Evite isso!

public class MyTestCase { @Test public void testSomething() { assertEquals(10, Calc.soma(7,3)); assertEquals(50, Calc.multiplica(5,10)); assertEquals(30, Calc.subtrai(50,20)); }}

Más práticas

● Múltiplos assertions. Forma correta:public class MyTestCase {

@Test public void testCondition1() { assertEquals(10, Calc.soma(7,3)); } @Test public void testCondition2() { assertEquals(50, Calc.multiplica(5,10)); } @Test public void testCondition3() { assertEquals(30, Calc.subtrai(50,20)); }}

Más práticas

● Método errado. Evite!

assertTrue("Os objetos devem ser o mesmo", expected == actual);assertTrue("Os objetos devem ser iguais", expected.equals(actual));assertTrue("O objeto deve ser nulo", actual == null);assertTrue("O objeto não pode ser nulo", actual != null);

Use:

assertSame("Os objetos devem ser o mesmo", expected, actual);assertEquals("Os objetos devem ser iguais", expected, actual);assertNull("O objeto deve ser nulo", actual);assertNotNull("O objeto não pode ser nulo", actual);

Más práticas

● Cobertura superficial– Caminho perfeito– Funcionalidades fáceis de testar– Alternativa: Code Coverage Tools

Más práticas

● Testes excessivamente complexos

Más práticas

● Testes excessivamente complexos

Refatorar até obter:

Más práticas

● Testes excessivamente complexos

Refatorar até obter:1.Configuração

2.Declaração dos resultados esperados

3.Executar método a ser testado

4.Recuperar resultado

5.Verificar resultado encontrado X esperado

Más práticas

● Capturar exceções Inesperadaspublic void testCalculation() {

try {

srv.calculate();

assertEquals(42,srv.getResult());

}catch(CalculationException ex) {

Log.error("Calculation caused exception", ex);

}

}

Más práticas

public void testCalculation() throw CalculationException { srv.calculate();

assertEquals(42,srv.getResult());}

● Forma correta: Não capture exceções inesperadas

Más práticas● Validando exceções. Forma correta:

@Test(expected=IndexOutOfBoundException.class)public void testIndexOutOfBoundsException() {

try {

ArrayList emptyList = new ArrayList();

Object o = emptyList.get(0);

}

}

Más práticas

Más práticas

Não

Más práticas

Não escrever

Más práticas

Não escrever Testes !!

Reflexão Final

"Todo programador sabe que é capaz de escrever testes para seu código. Poucos escrevem. A resposta universal para a pergunta

"porque não?" é "Eu estou muito ocupado". Essa atitude torna-se um ciclo: quanto mais pressão você sente, menos testes você escreve.

Quanto menos testes você escreve, menos produtivo você se torna e menos estável seu código fica. Quanto menos produtivo você se

torna, mais pressão você sente".*

* http://junit.sourceforge.net/doc/testinfected/testing.htm

Sobre o JUGMS

● Grupo de usuários Java do MS● Forte atuação em Campo Grande● Participa e promove eventos, palestras e

reuniões● Visite-nos: http://www.jugms.com.br

Sobre o Javaneiros

● Evento sobre todas as vertentes da tecnologia Java

● + de 500 inscritos em 2008● Edição 2009

– 14 de novembro de 2009 – Campo Grande/MS– Universidade Unaes– Entrada: 1 kg de alimento– Reservas especiais para caravanas– http://javaneiros.jugms.com.br

Sobre a Bacarin Software

● Residente na Incubadora de Empresas da UNIDERP

● Fornece sistemas web para:– Comércio Eletrônico– Web Sites– Gerenciamento Eletrônico de Documentos

● Visite-nos: http://www.bacarin.com.br

Dúvidas?

Bibliografia● http://pt.wikipedia.org/wiki/JUnit

● http://www.improveit.com.br/xp/praticas/tdd

● http://www.exubero.com/junit/antipatterns.html

● http://www.guj.com.br/java.tutorial.artigo.40.1.guj

● http://www.junit.org/junit/javadoc/3.8.1/junit/framework/Assert.html

● http://junit.sourceforge.net/doc/testinfected/testing.htm

● http://www-128.ibm.com/developerworks/opensource

/library/os-junit/?ca=dgr-lnxw07JUnite

● http://pt.wikipedia.org/wiki/Teste_de_software

● http://www.slideshare.net/jeveaux/*

● http://www.junit.org/node/574

Licença● Este material está licenciado sob a Licença Creative-Commons

Atribuição-Uso Não-Comercial-Compartilhamento pela mesma Licença 2.5 Brasil

● Você pode:

– Copiar, distribuir, exibir e executar a obra

– Criar obras derivadas

● Sob as seguintes condições:

– Atribuição. Você deve dar crédito ao autor original, da forma especificada pelo autor ou licenciante.

– Uso Não-Comercial. Você não pode utilizar esta obra com finalidades comerciais.

– Compartilhamento pela mesma Licença. Se você alterar, transformar, ou criar outra obra com base nesta, você somente poderá distribuir a obra resultante sob uma licença idêntica a esta.

Recommended