Testes de Unidade com JUnit
               Robinson Castilho – JUGMS
                 castilho@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 modelo
             de avião
Avião Moderno
Avião Moderno
             Bonito
Avião Moderno
             Bonito
Inovador
Avião Moderno
             Bonito
Inovador
         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
              produz
            SEMPRE
  uma mesma saída
Como testar
corretamente?
Caixa Preta
Caixa Preta

Não se preocupa com o
          código fonte
Caixa Preta

     Não se preocupa com o
               código fonte
Saídas são coerentes com as
                  entradas?
Caixa Preta

      Não se preocupa com o
                 código fonte
 Saídas são coerentes com as
                    entradas?
Equipe testes (normalmente)
        é diferente da equipe
              implementação
Caixa Branca
Caixa Branca

Trabalha com o código fonte
Caixa Branca

Trabalha com o código fonte
Avalia aspectos:
Caixa Branca

Trabalha com o código fonte
Avalia aspectos:
●
    Teste de condição
●
    Teste de fluxo de dados
●
    Teste de ciclos
●
    Teste de caminho lógico
●
    Código nunca executado...
Fases: Testes de Unidade
Fases: Testes de Unidade
Fases: Testes de Unidade

Testa o código
Fases: Testes de Unidade

Testa o código
Pequenas unidades
Fases: Testes de Unidade

Testa o código
Pequenas unidades
Independentes
Fases: Testes de Unidade

Testa o código
Pequenas unidades
Independentes
(sub-rotinas, trechos)
Teste de Integração
Teste de Integração
Testa a integração interna
            de um sistema
Teste de Integração
Testa a integração interna
            de um sistema
      Verifica se as peças
       do quebra-cabeças
         Estão encaixadas
Teste de Sistema
Teste de Sistema

Ponto de vista
do cliente final
Teste de Sistema

Ponto de vista
do cliente final
Teste de Sistema

Ponto de vista
do cliente final


Simular
ambiente
que o 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 restrito
             usuários finais
             simulam o uso
              em produção
Teste de Aceitação
                     Aprovado ou não?
                         Grupo restrito
                         usuários finais
                         simulam o uso
                          em produção
Determina se o sistema satisfaz os
critérios estabelecidos
JUnit
JUnit
automatizar testes de unidade
JUnit
automatizar testes de unidade

             Open Source
JUnit
automatizar testes de unidade

             Open Source

   Largamente Utilizado
JUnit
automatizar testes de unidade

             Open Source

   Largamente Utilizado

Criação rápida de testes
JUnit
          automatizar testes de unidade

                       Open Source

             Largamente Utilizado

          Criação rápida de testes

Diminuir necessidade de depuração
JUnit
                       automatizar 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 {
  @Test
  public void testSoma() {
        assertEquals(10, Calc.soma(7,3));
    }
}
Relatório no Eclipse
JUnit - Ciclo de vida




*DZone RefCardz
@Test

Informa que é um método de teste
Atributos:
●
    expected
●
    timeout
@Before e @After
Métodos executados
antes e após um método de teste (setUp e tearDown)
@Before e @After
Métodos executados
antes e após um método de teste (setUp e tearDown)




     @BeforeClass e @AfterClass
                            Métodos executados
                 antes e após uma classe de teste
Novidades do JUnit 4.7
Novidades do JUnit 4.7
Anotação: @Rule
Novidades do JUnit 4.7
Anotação: @Rule
Redefinir
e adicionar comportamentos
Novidades do JUnit 4.7
Anotação: @Rule
Redefinir
e adicionar comportamentos
Mecanismo 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 {
       @Rule
       public TemporaryFolder folder= new TemporaryFolder();

        @Test
        public 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() {
            @Override
            protected void before() throws Throwable {
                myServer.connect();
            }

             @Override
             protected 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
    public static class UsesErrorCollectorTwice {
        @Rule
        public ErrorCollector collector= new ErrorCollector();

        @Test public void example() {
            collector.addError(new Throwable("first thing went wrong"));
            collector.addError(new Throwable("second thing went wrong"));
        }
    }



●
    Veja mais em: http://www.junit.org/node/574
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