3. O que é TDD?
● Test Driven Development.
● Metodologia de desenvolvimento baseado em testes.
● Os testes unitários são escritos antes da funcionalidade.
5. O que é Teste Unitario?
Um teste unitário(de uma unidade) é o teste da menor parte
testável de um programa.
A unidade pode ser uma instrução, método, classe,
funcionalidade e etc.
Depende muito do que é a menor parte que seu software
pode ser testado.
Cada teste deve ser responsável por testar apenas um
comportamento
6. O Teste unitário deve ser (F.I.R.S.T.)
● Fast ⇒ Rápido;
● Independent ⇒ Independente;
● Repeatable ⇒ Repetitivo;
● Self-Verifiable ⇒ Auto-Verificável;
● Timily ⇒ Escrito no momento certo;
7. O que é Teste de Integração?
É o teste utilizando os recursos reais sem assistência de
test doubles, ou seja ele garante que tudo funciona
conforme testado.
8. Se eu tenho testes unitários, por que eu preciso de
testes de Integração?
9. Como Funciona
As 3 Leis do TDD
O desenvolvimento deve ser orientado por essas 3 leis:
1. You are not allowed to write any production code unless it is to make a failing unit test pass.
2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures
are failures.
3. You are not allowed to write any more production code than is sufficient to pass the one failing unit
test.
Essas 3 leis em resumo fazem alusão ao uso de “Baby Steps”.
Robert C. Martin
aka Uncle Bob
10. Ciclo de Desenvolvimento de Testes Unitários
1 - RED - Erro nos teste;
2 - GREEN - Corrigir o erro no teste ou
corrigir o teste, da maneira mais fácil
possível ;
3 - REFACTOR - Limpar a casa, uma vez
que seu teste passou, agora você pode
pensar na melhor maneira de fazer;
11. Formato do Teste
Temos os 3 A’s :
● Arrange - É a preparação, seja de ambiente, variáveis, banco de dados, test
doubles e etc. Tudo aquilo que o teste irá utilizar.
● Act - Realizamos a chamada do SUT(System Under Test)
● Assert - É o momento de verificarmos se o teste trouxe os resultados
esperados.
12. Vantagens
● Evita future proofing(?)
● Garante consistência
● Evita desperdícios
● Refatoração em ambiente seguro
● Os testes são uma documentação
● Reduz esforços de retrabalho
14. Desvantagens
● Tempo de desenvolvimento*
● Testes devem ser mantidos
● Deve ser um esforço de time
● Difícil ser aplicado em código legados
● No início tem custo alto no desenvolvimento
● Refatorações, requerem também a refatoração dos testes
15. O que ele não garante?
● Código livre de bugs
● Qualidade
● Ausência de Erros
17. Dummy
● São Placeholders, geralmente eles são usados apenas para preencher listas
de parâmetros.
● Poderia ser substituido por Null
● São objetos que não interagem diretamente com o SUT
● O conteúdo não é relevante, mas o objeto é obrigatório
@Test
public void addCustomerTest() {
//método privado no teste pra criar um customer qualquer
//Customer customer = createDummyCustomer();
//Ou
Customer dummy = mock(Customer.class);
AddressBook addressBook = new AddressBook();
addressBook.addCustomer(customer);
assertEquals(1, addressBook.getNumberOfCustomers());
}
18. Stub
● Fornecem respostas pré configuradas às chamadas feitas durante o teste.
● Podemos usar para testar o caminho feliz e os casos com exceção
public class AcceptingAuthorizerStub implements Authorizer {
public Boolean authorize(String username, String password) {
return true;
}
}
EntityManager entityManager = mock(EntityManager.class);
when(entityManager.find(Customer.class,1L)).thenReturn(sampleCustomer);
19. Spy
● Spies são Stubs que registram informações de suas iterações.
● Podendo ou não ser a chamada do método real
@Test
public void whenStubASpy_thenStubbed() {
List<String> list = new ArrayList<String>();
List<String> spyList = Mockito.spy(list);
assertEquals(0, spyList.size());
Mockito.doReturn(100).when(spyList).size();
assertEquals(100, spyList.size());
}
@Test
public void whenSpyingOnList_thenCorrect() {
List<String> list = new ArrayList<String>();
List<String> spyList = Mockito.spy(list);
spyList.add("one");
spyList.add("two");
Mockito.verify(spyList).add("one");
Mockito.verify(spyList).add("two");
assertEquals(2, spyList.size());
}
20. Mock
● Mocks são objetos configurados, onde define-se o comportamento das
chamadas esperadas durante o teste.
● Podem lançar uma exceção se receberem uma chamada que não
configurada
● Permite verificação dos comportamentos configurados
UUIDProvider uuidProvider = mock(UUIDProvider.class)
when(uuidProvider.isValid(uuid)).thenReturn(true);
UUID id = UUID.fromString(uuid);
when(uuidProvider.fromString(str)).thenReturn(id);
verify(uuidProvider).isValid(str);
verify(uuidProvider).fromString(str);
21. Fake
● É uma implementação real, voltada para os testes e que não será usada em
produção
● Tem um comportamento voltado regras de negócio
● Podem ser extremamente complexos
● Normalmente representam um serviço externo, tal qual um banco de dado,
ou um sistema de autenticação.
public class AcceptingAuthorizerFake implements Authorizer {
public Boolean authorize(String username, String password) {
return username.equals("Bob");
}
}
23. Escolas de TDD
Classicist (Detroit)
● Bottom-up / Middle-out
● Teste da API pública
● Avanço através de pequenos incrementos
● Liberdade para refatorações agressivas na
implementação
● Chances de criar um YAGNI
● Testes Superficiais, foco no resultado
● Teste de Regressão em uma única suíte
● Testa estado
Mockist (London)
● Top-down
● Teste de todas as camadas
● Alto acoplamento entre testes e
implementação
● Reescrever ao invés de re-fatorar
● Design Limpo e minimalista
● Grande quantidade de test doubles
● Teste regressão depende de mais de uma
suíte
● Testa Comportamento
24. System Under Test(SUT)
public BoletoVO listById(String id) {
if(uuidProvider.isValid(id)) {
UUID uuid = uuidProvider.fromString(id);
Optional<Boleto> bo =
boletoRepository.findById(uuid);
if(bo.isPresent()) {
return boletoMapper.mapToVO(bo.get());
} else {
throw new BankslipRecordNotFoundException();
}
}
throw new InvalidUUIDFormatException();
}