Gerência e Qualidade de Software - Aula 08 - Teste de unidade

Gerência e Qualidade de Software - Aula 08 - Teste de unidade

Teste de Unidade: Importância e Princípios

Introdução aos Testes Automatizados

  • Fábio Siqueira introduz o tema dos testes de unidade, enfatizando a automação como uma prática comum na atualidade.
  • Destaca que nem todos os testes podem ser automatizados, especialmente aqueles que envolvem usabilidade ou condições específicas.

Vantagens da Automação de Testes

  • A automação pode reduzir custos e tempo em comparação com testes manuais, mas é importante avaliar se vale a pena.
  • Executar testes automaticamente permite agilidade; um único botão pode rodar múltiplos testes rapidamente.
  • A frequência na execução de testes automatizados aumenta a chance de encontrar defeitos no software.
  • Os testes servem como documentação do funcionamento do software, ajudando desenvolvedores a entenderem melhor o código.
  • A confiança dos desenvolvedores aumenta ao saber que os testes estão cobrindo suas implementações.

Princípios para Testes Eficazes

Projetar Código para Testabilidade

  • O código deve ser projetado para facilitar os testes, sem necessidade de mudanças drásticas na estrutura original.

Nomeclatura Clara nos Testes

  • Nomes descritivos são essenciais para identificar facilmente o propósito e a função dos testes.

Independência dos Testes

  • Cada teste deve ser independente; falhas em um teste não devem afetar outros. Isso facilita a identificação da origem do problema.

Isolamento das Unidades

  • As unidades testadas devem estar isoladas para evitar que defeitos se propaguem entre elas.

Minimização da Sobreposição

  • Evitar sobreposição nos testes é crucial; isso reduz redundâncias e melhora a eficiência na execução.

Considerações Finais sobre Código de Teste

Importância dos Testes em Software

Riscos de Deixar Testes em Produção

  • Manter testes disponíveis no software em produção pode permitir que usuários explorem brechas, resultando em comportamentos inesperados.
  • É crucial testar uma condição por vez, evitando múltiplos testes simultâneos para garantir a eficácia do processo.

Tipos de Teste e Metodologias

  • Existem duas abordagens principais para testes: teste a priori (antes da codificação) e teste posterior (depois da codificação).
  • O teste unitário é frequentemente recomendado, pois oferece vantagens teóricas significativas.

Definição de Unidade de Teste

  • A unidade de teste pode ser definida como uma classe ou um método; há debates sobre qual abordagem é mais eficaz.
  • Dependendo da definição escolhida, os testes podem ser classificados como unitários ou de integração.

Exemplos Práticos com Classes

  • Um teste dentro de um método é sempre considerado um teste unitário, enquanto interações entre métodos diferentes são considerados testes de integração.
  • Se a unidade for uma classe, ainda se trata de um teste unitário mesmo que envolva várias chamadas sequenciais.

Frameworks e Estrutura dos Testes

  • O uso do framework JUnit é comum para testes unitários em Java; ele serve como padrão na indústria.
  • Os testes devem ser organizados em classes separadas para manter o código limpo e seguir boas práticas.

Estrutura Básica dos Testes Unitários

  • A estrutura básica envolve importar as bibliotecas necessárias e usar anotações específicas para definir métodos antes dos testes.

Métodos de Teste em Programação

Estrutura dos Testes

  • O método before é executado antes de cada teste, permitindo uma inicialização comum para todos os testes.
  • Cada teste é isolado em um método separado, anotado com a palavra-chave @Test, garantindo que sejam executados individualmente.
  • A nomeação dos métodos de teste deve ser sugestiva, facilitando a identificação do comportamento que está sendo testado.

Métodos Comuns de Verificação

  • Os métodos mais utilizados para verificação incluem condições que retornam verdadeiro ou falso; se a condição for falsa, o teste falha.
  • O método assertTrue verifica se uma condição é verdadeira; caso contrário, o teste falha automaticamente.
  • Para comparar valores flutuantes, utiliza-se um método específico que considera um erro aceitável (epsilon), evitando problemas com comparações diretas.

Isolamento e Dependências

  • É importante criar uma nova instância da classe (ex: calculadora) para garantir que os resultados de um teste não influenciem outros testes subsequentes.
  • Dependências entre classes podem complicar os testes; por isso, é essencial isolar a parte a ser testada.

Uso de Dublês em Testes

  • Para testar classes dependentes (como uma calculadora com memória), pode-se usar dublês para simular comportamentos sem depender da implementação real.
  • Um dublê deve ter a mesma estrutura e assinaturas da classe original, mas seu comportamento pode ser controlado conforme necessário durante os testes.

Injeção de Dependência

  • A injeção de dependência permite trocar implementações facilmente sem modificar o código existente.
  • Ao projetar classes para receberem suas dependências via construtores ou interfaces, facilita-se o uso de diferentes implementações durante os testes.

Estande como Dublê

Como Criar Testes de Unidade Eficazes?

Importância da Memória em Testes

  • A criação de uma classe específica para simular a memória é essencial para garantir que os testes respondam adequadamente às chamadas de métodos, como o método adicionar.
  • A classe "memória proteste" é simples e permite um teste isolado, evitando efeitos colaterais indesejados ao substituir a implementação original.

Desafios com Stubs

  • Um dos principais problemas ao usar stubs é a dificuldade em verificar se os métodos esperados foram chamados corretamente e se os parâmetros passados são adequados.
  • O retorno fixo dos stubs pode ocultar erros, pois não valida a sequência correta das chamadas de método.

Criação de Classes para Testes

  • É necessário criar uma nova classe para cada teste quando se utiliza stubs, o que pode ser trabalhoso e ineficiente.
  • Uma alternativa mais avançada é utilizar "mocks", que permitem verificações comportamentais sem a necessidade de classes separadas.

Dicas para Testes Estruturais

  • Recomenda-se começar com testes estruturais (caixa branca), considerando também os testes funcionais (caixa preta).
  • Ao definir valores nos testes, deve-se evitar cálculos complexos; recomenda-se inserir valores diretos para facilitar a identificação de falhas.

Evitando Erros Comuns em Testes

  • Não utilize valores aleatórios nos testes, pois isso dificulta a reprodução de falhas. Valores específicos devem ser usados para garantir consistência.
  • Métodos triviais que não apresentam comportamento significativo não devem ser testados, pois isso consome tempo sem agregar valor real aos testes.

Conclusão sobre Práticas de Teste

Video description

Engenharia de Computação - 16º Bimestre Disciplina: Gerência e Qualidade de Software – EES - 201 Univesp - Universidade Virtual do Estado de São Paulo Professor responsável pela disciplina: Fábio Levy Siqueira Playlist da disciplina: https://www.youtube.com/playlist?playnext=1&list=PLxI8Can9yAHcmjsfjFdo_xJ3xhLiczzLC