Escrevendo testes que valem a pena

Testes bem feitos adicionam valor. Testes ruins são apenas custo!

Software bom, que atende ao negócio com custo apropriado, demanda boas práticas de engenharia de software. Dentre essas práticas, destaca-se, sem dúvidas, o desenvolvimento de testes automatizados. Entretanto, não podemos ignorar o fato de que estes custam tempo e dinheiro, afinal, são códigos que precisam ser produzidos e mantidos. Quando são mal feitos, não compensam o investimento.

Testes difíceis de entender, por exemplo, aumentam o tempo que o programador precisa para fazer ajustes em uma base de código. Além disso, quando acusam falha, não ajudam a detectar rapidamente como resolver o que há de errado. Ou seja, mesmo que tenham valor por evitar erros em produção, poderiam agregar ainda mais.

Em bases de código C# não é raro encontrar testes verificando o funcionamento dos getters e setters. Entretanto, convenhamos que esse funcionamento é garantido pela Microsoft e, seguramente, já foi testado por seus programadores.

public class Customer
{
  public string Name { get; set; }
  // ..
}

/* ------------------------------------- */
public class CustomerTests
{
  public void GetterAndSetterWorkForNameProperty
  {
    var c = new Customer();
    c.Name = "John Doe";
    Assert.Equal("John Doe", c.Name);
  }
}

Há também aqueles testes que, embora adicionem algum valor, quebram facilmente durante a evolução do sistema. Em suma, são testes frágeis com alto custo de manutenção. Por exemplo, testes de construtores que inicializam propriedades de uma classe.

public class CreateUserCommand
{
   public CreateUserCommand(string name)
   {
      Name = name ?? throw new ArgumentNullException(nameof(name));
   }
   
   public string Name { get; }
}

/*-------------------------*/
public class CreateUserCommandTests
{
    [Fact]
    public void UserNameIsMandatory()
    {
       Assert.Throws(() => new CreateUserCommand(null));
    }
}

Testes ruins valem menos que o espaço que consomem nos dispositivos de armazenamento. Mais que isso, são também dívidas técnicas pois geram impacto negativo para o negócio e para os times técnicos.

De forma objetiva, o custo para desenvolver e manter software com testes deve ser menor do que seria se não houvesse teste algum. Quando não é assim, há algo muito errado.

Bons testes protegem contra regressão, dão segurança para atividades de refatoração, contribuem para a redução do lead time e reduzem os custos de manutenção. Com o tempo, boas bases de testes também ajudam a previnir erros, mas este é apenas um efeito colateral positivo.

Testes podem ser usados apenas para demonstrar a presença de bugs, nunca a ausência! – Edsger W. Dijkstra

Em Resumo
  • O fato

    Software bom, que atende ao negócio com custo apropriado, demanda boas práticas de engenharia de software. Dentre essas práticas, destaca-se, sem dúvidas, o desenvolvimento de testes automatizados. Porém, se estes forem ruins, acabam apenas adicionando custos.
  • O insight

    É importante garantir que os testes reduzam o tempo necessário para que programadores entendam o sistema, eles devem ser realmente relevantes e, finalmente, não devem ser frágeis. Testes ruins valem menos que o espaço que consomem nos dispositivos de armazenamento.
  • Os benefícios

    Bons testes protegem contra regressão, dão segurança para atividades de refatoração, contribuem para a redução do lead time e reduzem os custos de manutenção. Com o tempo, boas bases de testes também ajudam a previnir erros, mas este é apenas um efeito colateral positivo.

Rafael Amaral

Atuo na área de desenvolvimento de software como programador e tech leader. Meus principais interesses são Arquitetura, Code Quality, Liderança e Agile. Alem disso, gosto de Literatura, Filosofia e Finanças ... E tudo isto banhado com muito Metal.

Talvez você goste também

Carregando posts…

Mais posts da série Escrevendo testes que valem a pena

6 Comentários
  1. ISMAEL GASPARIN

    Faltou adicionar exemplos de testes bons e como chegar neles.

    1. Rafael Amaral

      Olá Ismael, obrigado pelo seu feedback.

  2. Mail Braga

    Elemar, seria interessante nós apresentar bons testes. As vezes eu sinto que escrevo testes desnecessários onde só existe custo para o projeto. Essa parte do seu texto ficou muito ubscura “Testes ruins valem menos que o espaço que consomem nos dispositivos de armazenamento.”, cknsegue na explicar?

    1. Rafael Amaral

      Olá Mail Braga,
      A ideia deste trecho é passar a percepção que um teste quando mau escrito é somente custo para o seu projeto.
      Obrigado.

  3. Everton Castro

    Confesso que o tema testes é uma coisa que me deixa com bastante dúvida. Sempre ouvi que teste bom é aquele que quebra quando alguma parte razoável é alterada. Se não quebra pode ser uma baixa cobertura ou teste mal feito que apenas testou cenários de sucesso e não o de erro, deixando um bug silencioso no código. Na experiência de vocês isso faz sentido ou a perspectiva na hora de criar os testes deve ser outra?

    1. Rafael Amaral

      Everton você citou duas categorias essenciais para um teste de qualidade que são “Protection against regression” e “Resistance to refactory”. Na minha experiência, proteger o código de qualquer regressão é inegociável, logo todo teste deve de alguma forma proteger o System Under Test de regressões. Entretanto, o post acima tem como principal objetivo provoca-los a observar que escrever testes sem o devido cuidado é custo.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *