Automatizando testes em 4 passos

Preview:

DESCRIPTION

Apresentação feita para a equipe da RBS sobre automatização de testes. Em quatro passos, verificamos qual a parte do nosso código que precisa mais atenção, e auxiliado por ferramentas ampliamos a confiabilidade dos códigos.

Citation preview

AutomatizandoTESTES

em quatro passos

@helmedeiros

1. Conhecimentos básicos de testes2. Cobertura de testes com Emma3. Desenvolvendo testes unitários com JUnit4. Testes unitários com objetos dubles usando mockito

4

Conhecimentos básicos de testes

1

estresse

execução de testes

Gerry Weinbergdiagrama de influência

menor

menor

quantomaior

testar significa “avaliar”

em produção o estresse é bem maior

Top Down

Bottom up

cenários de teste... critérios de aceitação...

22 caixas de texto... 15 combo box...

ISOLATED TEST - Teste Isolado

QUEBROU UMA PARTE QUE NÃO DEVIA

FIZuma mudança

1.A execução dos testes deve ser rápida;

2.A execução de um teste deve ignorar as demais;

Kent BeckTDD - Desenvolvimento Guiado por Testes

O que mais deveria testar?

TEST LIST - Lista de testes

1.Coloque na lista exemplos das operações que você sabe que precisa implementar;

2.Para todas já implementadas coloque a versão de conferência nula;

3.Liste todas as refatorações que você acha que terá de fazer para limpar o código.

Kent BeckTDD - Desenvolvimento Guiado por Testes

TESTEImeu código

1. Qual o conjunto de testes, que quando passarem, demonstrará que o código que estamos confiantes que irá calcular o relatório corretamente?

$5 + 10 CHF = $10 se a taxa é 2:1$5 * 2 = $10

Tornar a “quantidade” privadaEfeitos colaterais em Dollar?Arredondamento de dinheiro?

Kent BeckTDD - Desenvolvimento Guiado por Testes

TEST FIRST - Teste primeiro

QUANDO EU DEVO ESCREVER MEUS TESTES?

ESCREVImeu código

1.Primeiro escreva os testes;

2.Depois escreva o código com o escopo e designe controlado;

Kent BeckTDD - Desenvolvimento Guiado por Testes

ASSERT FIRST - Defina a asserção primeiro

COMO EU FOCO A FUNCIONALIDADE E NÃO NO TESTE ?

ESCREVImeu teste

1.Primeiro escreva a asserção que passará quando o código estiver certo;

2.Depois resolva de baixo para cima as dependências;

Kent BeckTDD - Desenvolvimento Guiado por Testes

Quando eu testo definindo uma asserção primeiro, defino como reversa a minha lógica de construção, resolvendo um problema por vez.

Quando pronto o socket deve estar fechado e deveríamos ter lido a string abc

1 2De onde a resposta vem? Do socket, certamente:

3E o socket? Nós o criamos conectando ao servidor:

4Mas, antes disso, precisamos abrir o servidor:

Kent BeckTDD - Desenvolvimento Guiado por Testes

TEST DATA - Dados de teste

A ORDEM DOS PARÂMETROS IMPORTA?

ESCREVImeu teste

1.Use dados que façam os testes fáceis de ler e seguir;

2.Quando a ordem dos parâmetros de chamada fizer diferença use dados diferentes;

Kent BeckTDD - Desenvolvimento Guiado por Testes

EVIDENT DATA - Dados evidentes

O QUE SIGNIFICA NO SEGUNDO PARÂMETRO O VALOR 3?

ESCREVImeu teste

1.Pense em qual o objetivo do dado;

2.Defina uma constante que transpareça este objetivo;

*Não utilize a mesma constante duas vezes para casos diferentes.

Kent BeckTDD - Desenvolvimento Guiado por Testes

Todos os parâmetros de um método devem ser claros enquanto as suas intenções, assim como deve ser sua utilização. Devemos SEMPRE evidenciar o objetivo de cada valor.

Constantes com o mesmo valor são diferidas pelo nome da constante.

1

O nome da constante diferencia os significados/intenções de cada parâmetro dentro da requisição e por conseguinte as cenário de teste.

CaelumFJ-16: Laboratório Java com Testes, XML

2

TDD

qual o primeiro cenário que desejo resolver?

1 quais as soluções para o problema?

2

3 qual o próximo cenário?

RESOLVIDO X

Desenvolvimento guiado por testes

n++

red

escrever um teste que falhe!escolher um problema

greenfazer ele passar o mais rápido possível!

yellodepois refatorar até achar que está bom!

NOSSO PROBLEMAFizzBuzz

dada uma lista de 1 a 100

12

Fizz4

BuzzFizz78

FizzBuzz

11Fizz1314

FizzBuzz

{múltiplos de 3múltiplos de 5

múltiplos de 3 e 5

2Cobertura de testes com Emma

test coveragecobertura de testes

é qualquer medida de abrangência relacionada a um requisito ou a um critério de design/implementação do código, como a verificação de casos de uso ou execução de todas as linhas de código.

test coveragecobertura de testes

ENCONTRARcódigo não testado

GARANTIRqualidade do códigoX

statement coverage

multiple conditions coverage

se detêm ao simples registro sobre quais linhas foram executadas.

mede cada condição lógica no código avaliando se existem cenários não testados.

multiple conditions coveragemede cada condição lógica no código avaliando se existem cenários não testados.

Instrumentação

execução dos testes

originalcódigo

avaliadocódigo

multiple conditions coveragemede cada condição lógica no código avaliando se existem cenários não testados.

A ferramenta de cobertura modifica o código para registrar quais expressões avaliar em qual caminho.

Esta modificação pode ser feita tanto para o código-fonte quanto para o executável que o compilador gera.

Se for feito de código-fonte, a maioria das ferramentas não alteram a fonte original, em vez disso, eles modificam uma cópia que é então passada para o compilador de uma maneira que faz parecer que é o original.

Após a instrumentação, você deve executar vários testes, acumulando resultados de cobertura em alguns log.

Instrumentação

multiple conditions coveragemede cada condição lógica no código avaliando se existem cenários não testados.

Códigos com condições lógicas são instrumentados, e após a execução são apresentados logs que descrevem dentre as possíveis condições quais não foram testadas.

1Código limpo, com condições lógicas:

2Código testado, com diferentes logs para as condições lógicas:

EclEMMA

JaCoCo

ferramenta de cobertura de código para o Eclipse.

JaCoCo é uma biblioteca livre de cobertura de código para Java.

A execução de testes e cobertura não devem ser deixado para a fase de build e deploy, nem muito menos serem restritas as ferramentas de continuous deployment, todo desenvolvedor deve ser capaz de executar quantas vezes necessário antes de comitar seu código.

32

1

EclEMMA

Cada execução da bateria de testes e cobertura de seu código realizada pelo eclipse lhe conduzirá a um novo cenário de testes. Para cada cenário avalie o resultado esperado e crie um novo teste para aumentar a cobertura sob o aspecto.

EclEMMA1 2

3

O que o seu código devera fazer? Liste os cenários e em seguida as

asserções para cada um destes.

Execute a bateria de testes de cobertura apertando no nome do

método ou da classe.

Analise o relatório e veja oque ainda falta ser avaliado.

JaCoCo

Scripts de execução de testes e de cobertura são abstrações menores, e desta forma devem ser preferíveis a grandes alterações ou escolhas estruturais. O JaCoCo e o Emma são excelentes e enxutas bibliotecas para execução na maquina dos desenvolvedores e serviços de deploy.

1Criar targets para executar testes

no junit, com apontamentos para os arquivos do emma.

2Criar target para execução da instrumentação pelo emma.

3Criar target para criação dos

reports baseados nos arquivos gerados após a execução dos

testes.

JaCoCo

A execução de testes e cobertura devem ser repetidos na fase de build e deploy, com o apoio das ferramentas de continuous deployment, todo membro da equipe deve saber como está a qualidade e a confiança no código entregue com métricas acionáveis, acessíveis e auditáveis.

JaCoCo

A execução de testes e cobertura devem ser repetidos na fase de build e deploy, com o apoio das ferramentas de continuous deployment, todo membro da equipe deve saber como está a qualidade e a confiança no código entregue com métricas acionáveis, acessíveis e auditáveis.

Gráficos de cobertura de testes, especificos por build, detalhados em pacotes.

NOSSO PROBLEMAFizzBuzz

(COBERTURA DE TESTES)

dada uma lista de 1 a 100

12

Fizz4

BuzzFizz78

FizzBuzz

11Fizz1314

FizzBuzz

{múltiplos de 3múltiplos de 5

múltiplos de 3 e 5

3Desenvolvendo testes unitários com JUnit

Teste unitárioapenas sobre uma classe

Um teste de unitário é um pedaço de código (normalmente uma classe) que chama um outro pedaço de código e verifica a exatidão de alguns pressupostos. Se os pressupostos estiverem errados, o teste de unidade falha.

RelatórioRelatórioX sucessos

Y falhas

Z erros

Suite de Teste

teste fixture

teste unitário

test case test case test case

test case test case test case

teste fixture

teste unitário

test case test case test case

test case test case test case

test case test case

test case test case test runner

executar

executar

test case

test case

•assertEquals(expected, actual) •assertEquals(String message, expected, actual)•assertSame(Object expected, Object actual) •assertSame(String message, Object expected, Object actual)•assertNotSame(Object expected, Object actual) •assertNotSame(String message, Object expected, Object actual)•assertNull(Object object) •assertNull(String message, Object object)

•assertNotNull(Object object) •assertNotNull(String message, Object object)•assertTrue(String message, boolean condition)•assertTrue(boolean condition)•assertFalse(String message, boolean condition)•assertFalse(boolean condition)•fail()•fail(String message)

A razão pela qual usamos testes em métodos ágeis é para que tenhamos especificações executáveis, adequadas sobre o que está sendo desenvolvido. Essas especificações devem falar sobre o que uma unidade faz, não sobre como ele executa suas tarefas.

@Before@BeforeClass@After

@AfterClass@Ignore@Test(expected=...)

A elaboração dos cenários de teste envolvem a reflexão lógica, ou a evolução na forma de sincronizar fixtures que devem ser sincronizados tendo em mente o ciclo de execução dos testes.

@BeforeClass

TEST CASE

@Before

@After

@AfterClass

Suite de testes

Comumente um conjunto de testes unitários devem ser executados em conjunto, seja devido a considerações enquanto ao raio de danos que uma alteração possa causar ou sentido funcional. Para isso usamos as Suites de teste.

3Execute a suite de testes, e

analise o conjunto dos relatórios.

2Defina a estratégia de

agrupamento e quais são as classes que fazem parte deste.

1Crie uma JUnit Test Suite

nomeando-a apropriadamente

fixtures

Maior parte do tempo você estará criando objetos que supram e especifiquem suas necessidades para seus casos de teste. Quando acontecer utilize Builders|ObjectMother como formas de especificar apenas o necessário.

2Crie uma classe Builder para seu

objeto.

3Utilize os builders para tornar

mais legível cada uma das opções.

1Crie uma JUnit Test Suite

nomeando-a apropriadamente

http://www.aniche.com.br/2011/09/testando-datas-e-metodos-estaticos/

testando métodos estáticos

“Métodos estáticos dificultam a escrita de testes de unidade. Para resolver isso podemos: evitar a escrita de métodos estáticos, ou criar abstrações que escondem esses métodos. Nao é feio criar abstrações como a Relogio; feio é não testar!” http://www.aniche.com.br/

1encontre locais onde você utiliza métodos estáticos que precisam

ser simulados para seus casos de teste.

2Defina uma interface a ser

utilizada no sistema em seu lugar

3Declare o campo em sua classe e

em seguida substitua o mesmo pelas antigas chamadas estáticas.

4Injete o objeto com o

comportamento que retorne como hoje o valor desejado

tratando exceções

Um erro sem mensagem, ou sem referencias aninhadas pode ser uma pedra no sapato. Desta forma tratar exceções na maior parte das vezes deve estar relacionada as mensagens retornadas, assim como o tipo de erro.

2Defina apenas a exceção

esperada no bloco try catch. Manter throw da exceção

recebida. E adicionar assert para mensagem.

1encontre locais onde você utiliza métodos estáticos que precisam

ser simulados para seus casos de teste.

NOSSO PROBLEMAFrutas

(JUnit, Builders e ObjectMother)

4Testes unitários com objetos dubles usando mockito

Test Double

mocks, stubs, fake e dummys

Muitas vezes objetos sob teste dependem de outros objetos, sobre os quais não temos nenhum controle (as vezes nem funcionam ainda). Neste caso usamos os dublês de teste, quaisquer objetos falsos, utilizado no lugar de um objeto real, com propósitos de teste.

“There is no object-oriented problem that cannot be solved by adding a layer of indirection, except, of course, too many layers of indirection.”

stubobjetos que possuem respostas pré-configuradas, não quebram teste quando não chamados.

mockobjetos que esperam ser acionados de uma forma específica, falham quando não chamados.

stubs

Muitas vezes, precisamos que nossa classe de teste se comporte de uma determinada maneira, com pontos de verificação temporários, ou ainda com uma implementação que não faz sentido em produção. Durante os testes usará acesso ao filesystem ao invés de base de dados.

1quando verificarmos um objeto a ser testado, ou

auxiliar que não necessitar uma verificação de comportamento, apenas de estado.

2Devemos criar uma interface para

o mesmo e substituí-lo por sua implementação.

3Criar uma implementação com o

comportamento desejado, e esperado.

Muitas vezes precisamos verificar o comportamento de um objeto principal ou auxiliar em uma dada funcionalidade. Para estes casos o mais indicado é a utilização dos MOCKS.

mocks

3Devemos verificar o

comportamento do mesmo.

1quando verificarmos um objeto a ser testado, ou

auxiliar que necessitar uma verificação de comportamento.

2Devemos criar um mock para o mesmo.

Mockito é um framework de mocking, que permite escrever testes bonitos com API limpa e simples.

•Cria Mocks de classes concretas assim como interfaces;

•Anotações com syntax sugar; (@Mock)

•Verificação dos erros é simplificada;

•Suporta a verificação do exato numero assim como no mínimo um acesso de método;

•Possuí verificação ou stub simplificado e flexível com utilização de matchers (anyObject(), anyString() ou refEq());

•Permite a criação de matchers customizados para argumentos usando hamcrest;

Recommended