Conceitos de Testes

JUnit 5, Mockito e testes com Spring — conceitos essenciais explicados a fundo.

Ordenar
1
Java

Ciclo de Vida dos Dados de Teste e o que Testar na Camada de Banco de Dados

Por que limpar os dados de teste no início compensa mais do que no fim, por que bancos em memória ainda não pertencem a testes de integração apesar de o Testcontainers mudar o trade-off do overhead de containers, e por que leituras e repositórios merecem uma régua de qualidade mais baixa do que escritas.

2
Java🔬 Lab

Pré-requisitos de Teste de Banco de Dados e Gerenciamento de Transações

Por que o schema e os dados de referência pertencem ao controle de versão, por que a entrega baseada em migração vence a baseada em estado assim que dados reais existem (o argumento de movimentação de dados), e por que testes de integração precisam de uma transação separada por seção de arrange/act/assert em vez de reutilizar uma única sessão.

3
Java🔬 Lab

Reutilizando Fixtures de Teste, Testes Parametrizados e Bibliotecas de Asserção

Por que a reutilização de fixtures baseada em construtor/@BeforeEach acopla os testes entre si e prejudica a legibilidade, por que métodos de fábrica privados (Object Mother) são o padrão melhor, quando recorrer a @ParameterizedTest e @MethodSource, e como o estilo fluente do AssertJ evita a armadilha da ordem de argumentos expected/actual.

4
Java

Estruturando e Nomeando Testes Unitários: AAA e Nomes em Inglês Simples

As regras reais do padrão AAA além de \"use três seções\": nunca escreva múltiplas seções de act ou um if dentro de um teste, trate uma seção de act com mais de uma linha como um mau cheiro no código de produção e não um problema do teste, e rejeite a nomenclatura rígida MethodUnderTest_Scenario_Result em favor de nomes de teste em inglês simples.

5
Java

Boas Práticas de Mocking: Só em Testes de Integração, Spies e Tipos que Você Possui

Regras concretas, às vezes contra-intuitivas, para usar mocks bem, além da distinção mock-vs-stub: mocks pertencem só a testes de integração, nunca a testes unitários de lógica de domínio pura; spies escritos à mão costumam vencer o verify() de um mock genérico; asserções precisam checar a contagem de chamadas, não só a ocorrência; e você só deveria mockar tipos que sua própria base de código define.

6
Java🔬 Lab

Anti-Padrões de Teste Unitário: Métodos Privados, Conhecimento de Domínio Vazado, e Tempo

Por que testar métodos privados, expor estado privado, reimplementar a lógica do SUT em um teste, poluir o código de produção com switches só para teste, mockar classes concretas, e chamar o relógio do sistema diretamente remontam todos à mesma causa raiz, do Khorikov, Capítulo 11 \"Unit testing anti-patterns\".

7
Java

Arquitetura Funcional: Separando Decisões de Efeitos Colaterais para Testabilidade

Aprenda o padrão functional-core/imperative-shell para tirar decisões de negócio de código carregado de efeitos colaterais, tornando a lógica de decisão trivialmente testável por saída com zero mocks, e entenda os custos reais: um shell que ainda precisa de testes de integração, overhead de alocação por imutabilidade em caminhos quentes, e lógica de domínio que nem sempre pode ser separada de forma limpa.

8
Java

Teste Baseado em Saída, em Estado, e em Comunicação

As três formas de um teste unitário verificar comportamento: checar uma saída retornada, checar o estado resultante, ou checar uma chamada feita a um colaborador, e por que o teste baseado em saída produz os testes de mais alta qualidade mas só funciona para código livre de efeitos colaterais, deixando o teste baseado em estado como o padrão razoável e o teste baseado em comunicação (mocks) como a exceção rara.

9
Java🔬 Lab

Comportamento Observável vs. Detalhes de Implementação: Por que Mocks Deixam os Testes Frágeis

Um mock (comando de saída) e um stub (consulta de entrada) respondem a perguntas diferentes, e afirmar sobre interações com um stub é um erro clássico de overspecification. O princípio mais profundo: mocking em si não causa testes frágeis, mockar uma interação que é um detalhe de implementação (intra-sistema, sem objetivo de cliente por trás) em vez de comportamento observável (uma chamada que cruza a fronteira da aplicação e permanece visível fora dela) causa. A correção não é evitar mocks, é mockar apenas em verdadeiras fronteiras do sistema.

10
Java

Dependências Gerenciadas vs. Não Gerenciadas em Testes de Integração

Por que um teste de integração deve acessar um banco de dados real (uma dependência gerenciada) mas mockar um servidor SMTP ou barramento de mensagens (uma dependência não gerenciada), e por que mockar uma dependência gerenciada quebra silenciosamente a resistência à refatoração.

11
Java

Escolas Clássica vs. London de Teste Unitário

Duas definições genuinamente diferentes de \"isolamento\" em teste: mockar todo colaborador (London) versus mockar só dependências compartilhadas/voláteis (clássica), e por que discordam sobre o que é uma unidade.

12
Java

Teste por Tipo de Código: Os Quatro Quadrantes

Um mapa de código de produção por complexidade/significância de domínio e número de colaboradores: onde o teste unitário compensa mais, onde é desperdício, e como o padrão Humble Object corrige o código que é genuinamente difícil de testar.

13
Java🔬 Lab

Os Quatro Pilares de um Bom Teste Unitário

Proteção contra regressões, resistência à refatoração, feedback rápido e manutenibilidade: os quatro atributos que julgam qualquer teste automatizado, e por que nenhum teste consegue maximizar os quatro ao mesmo tempo.

14
Java

A Estratégia da Pirâmide de Testes

Como distribuir testes entre níveis: muitos testes unitários rápidos na base, cada vez menos testes de integração/sistema/aceitação em direção ao topo, o que testar em cada nível, e qual ferramenta se encaixa em cada um, do JUnit in Action, Third Edition, Cap. 22.

15
Java

BDD com Cucumber

Escrevendo especificações de comportamento em Gherkin legível pelo negócio (Given/When/Then) e ligando-as a step definitions Java com Cucumber, com a configuração atual io.cucumber + JUnit 5 Platform substituindo o info.cukes/@RunWith(Cucumber.class) obsoleto do livro, do JUnit in Action, Third Edition, Cap. 21.

16
Java

Desenvolvimento Orientado a Testes

O ciclo red-green-refactor: escreva primeiro um teste que falha, adicione o menor código para passá-lo, então refatore com segurança, conduzindo o design com JUnit 5, do JUnit in Action, Third Edition, Cap. 20.

17
Spring🔬 Lab

Testando JPA e Hibernate

Testando uma camada de persistência JPA/Hibernate: mapeamento de entidade, persistence.xml, e queries de EntityManager contra um banco de dados de teste, com a mudança crítica de pacote javax para jakarta (Hibernate 6 / Spring 6), a fatia @DataJpaTest, e o Testcontainers para testes de integração com banco de dados real, do JUnit in Action, Third Edition, Cap. 19.4-19.6.

18
Spring🔬 Lab

Testando JDBC e Spring JDBC

Testando código de acesso a dados contra um banco de dados em memória, do JDBC puro (Connection/PreparedStatement/ResultSet) ao JdbcTemplate/NamedParameterJdbcTemplate do Spring, com notas sobre o carregamento obsoleto de driver via Class.forName, o JdbcTemplate injetado em vez do JdbcDaoSupport, e a fatia @JdbcTest, do JUnit in Action, Third Edition, Cap. 19.1-19.3.

19
Spring🔬 Lab

Testando uma API REST com MockMvc

Controlando um controller REST do Spring pelo MockMvc: requisições HTTP simuladas, asserções de status/content-type/jsonPath, e uma camada de dados mockada, com a fatia @WebMvcTest de hoje, o @MockitoBean (substituindo @MockBean), e a mudança do NestedServletException no Spring 6, do JUnit in Action, Third Edition, Cap. 18.

20
Spring🔬 Lab

Testando Aplicações Spring Boot

Inicializando um contexto de aplicação completo com @SpringBootTest: varredura de componentes, auto-configuração e autowiring de beans, além das fatias de teste mais rápidas de hoje (@WebMvcTest, @DataJpaTest) e a mudança @MockBean para @MockitoBean, do JUnit in Action, Third Edition, Cap. 17.

21
Spring🔬 Lab

Testando Spring com SpringExtension

Carregando um ApplicationContext do Spring em um teste JUnit 5 com @ExtendWith(SpringExtension.class) e @ContextConfiguration, injetando beans via @Autowired, com uma nota sobre o atalho @SpringJUnitConfig de hoje, do JUnit in Action, Third Edition, Cap. 16.

22
Java

Testes de Navegador com Selenium

Controlando um navegador real pela interface WebDriver: busca de elementos, testes parametrizados entre navegadores, e o modelo Page Object, com notas sobre o que mudou do Selenium 3 do livro para o Selenium 4 de hoje, do JUnit in Action, Third Edition, Cap. 15.

23
Java

Modelo de Extensão do JUnit 5

Os cinco pontos de extensão (execução condicional, callbacks de ciclo de vida, resolução de parâmetros, tratamento de exceções, pós-processamento de instância) por trás do @ExtendWith, o mesmo mecanismo que MockitoExtension e SpringExtension usam, do JUnit in Action, Third Edition, Cap. 14.

24
Java🔬 Lab

Test Doubles: Stubs e Mocking

Stubs vs. mocks como duas estratégias para falsificar um colaborador, e como criar e verificar mocks com Mockito, do JUnit in Action, Third Edition, Cap. 7-8.

25
Java

Qualidade de Teste e Código Testável

Medindo cobertura com JaCoCo, escrevendo código testável (Lei de Demeter, composição em vez de condicionais), e como TDD/BDD/teste de mutação se encaixam no ciclo de desenvolvimento, do JUnit in Action, Third Edition, Cap. 6.

26
Java

Princípios de Teste de Software

Teste unitário vs. integração vs. sistema vs. aceitação, e caixa-preta vs. caixa-branca: o vocabulário por trás de como uma suíte de testes é organizada, do JUnit in Action, Third Edition, Cap. 5.

27
Java

Arquitetura do JUnit 5

Como Platform, Jupiter e Vintage se encaixam para rodar testes novos e legados lado a lado, mais uma referência rápida de migração de JUnit 4 para 5, do JUnit in Action, Third Edition, Cap. 3.1/3.3 (e uma nota curta do Cap. 4).

28
Java🔬 Lab

Fundamentos do JUnit 5

O ciclo de vida de teste do JUnit 5, asserções vs. suposições, testes aninhados/marcados, e testes parametrizados/dinâmicos, do JUnit in Action, Third Edition, Cap. 2.