Desenvolvendo Testes Mais Coesos e Sem Code Smells

Chrystian Costa da Rosa
Bee Lab Academy
Published in
4 min readOct 1, 2020
geeksforgeeks.org

Muito se discute hoje em dia a respeito das diversas formas de se codificar os testes automatizados, independente da linguagem de programação. Em meio as regras e convenções, encontram-se alguns costumes disfarçados de padrões.

Mas até aonde nossos costumes nos ajudam?

Será que realmente fazem sentido ou são apenas pretextos para evitarmos as mudanças?

Com o que estamos em conformidade exatamente?

Foram esses questionamentos que me levaram a pesquisar um pouco mais sobre o assunto e, entre as diversas fontes que encontrei, escolhi a base de regras do SonarSource como parâmetro para abordar alguns tópicos.
SonarSource é uma empresa que desenvolve software de código aberto para a qualidade e segurança de código, detectando problemas de manutenção, confiabilidade e vulnerabilidade em mais de 20 linguagens de programação. Entre seus principais produtos estão o SonarLint, o SonarQube e o SonarCloud, que você provavelmente deve conhecer pelo menos um deles.

Como foco para o artigo escolhi testes na liguagem Java, filtrei as regras que mais se encaixam em meu contexto e selecionei as mais relevantes (no ponto de vista) e adicionei alguns outros tópicos importantes.

Regras de desenvolvimento de testes anti code smells

  • As classes de teste devem seguir uma convenção de nomenclatura (RSPEC-3577)
    Busque definir um padrão “universal” para as classes de testes em todos os seus projetos, preferencialmente, adicionando um sufixo no nome das classes. Os padrões comumente usados e muitas vezes reconhecidos automaticamente pelos frameworks são *Test, *Tests e *TestCase. Por exemplo, se a classe a ser testada é Account.java use algo como AccountTest.java.
  • TestCases devem conter testes (RSPEC-2187)
    Como mencionado anteriormente, entende-se por convenção que as classes com sufixo Test, Tests, ou TestCase são classes de testes(ou test cases), sendo assim, não utilize esse padrão para nomear classes que não contenham testes. Mas se for realmente necessário, prefira colocar Test como prefixo.
  • Os métodos de teste devem seguir uma convenção de nomenclatura (RSPEC-3578)
    Assim como as classes, os métodos também precisam seguir um padrão de nomenclatura. Se você ainda não tem um, experimente adotar. Não só deixa seus testes em conformidade, como também ajuda na compreensão do seu código. Por exemplo:
    Ao invés de usar createAccount() tente testCreateAccount() ou então mustCreateAccount().
  • Testes devem conter asserções (RSPEC-2699)
    Parace besteira, mas não é.
    Sim, existem situações em que pessoas desenvolvem testes sem asserções. Na verdade, se não tem validações, não é bem um teste, está mais é para um “robô”.
  • Argumentos de asserção devem ser passados na ordem correta (RSPEC-3415)
    Verifique sempre a ordem dos argumentos esperado e atual para não gerar falsos positivos/negativos.
  • Valores booleanos literais não devem ser usados ​​em asserções (RSPEC-2701)
    Não use assertTrue(true) ou similares, a não ser que você queira enganar a si mesmo. rsrs
  • Matenha os testes nas classes de testes (RSPEC-2186)
    As asserções não devem ser usadas nos métodos que não são de testes como “run”, por exemplo, porque as asserções com falha resultam em AssertionErrors, se o erro for lançado de uma thread diferente daquela que executou o assert, a thread será encerrada, mas a asserção não falhará.
  • Thread.sleep não devem estar presentes nos testes (RSPEC-2925)
    Por favor, remova imediatamente!
    Usar Thread.sleep em um teste geralmente é uma má ideia. Ele fragiliza os testes que podem falhar de forma imprevisível, dependendo do ambiente, ou da carga.
    Uma ótima alternativa é usar o Awaitility, uma biblioteca gratuita, prática e muito útil para implementar esperas e condições em testes assíncronos.
  • Não use mais de um test runner framework (TestNg, JUnit, etc)
    Isso pode facilmente causar erros nos seus testes, você pode se confundir na utilização e importação e quando o erro acontecer, você vai demorar uma vida para identificar o que está causando.
  • Para fechar com chave de ouro: Utilize o padrão AAA(Arrange-Act-Assert)
    Arrange-Act-Assert no bom português seria “Organizar, Agir e Verificar”. É um padrão para formatar o código nos métodos de testes de forma que fiquem organizados, limpo e de fácil entendimento:

    //Arrange: Organize todas as condições e entradas necessárias.
    //Act: Atue no objeto ou método que irá gerar o resultado.
    //Assert: Verifique se estão de acordo com os resultados esperados.

    * Cada método deve agrupar essas seções funcionais, separadas por linhas em branco.

Palavras finais

É de suma importância que tenhamos embasamento nos padrões adotados em nossos projetos, buscando sempre seguir boas práticas de desenvolvimento.

Uma excelente dica que lhe ajudará a seguir essas e outras regras, adicionar plugins às suas IDEs que façam essa análise no código, como o plugin do SonarLint, por exemplo.

Ficamos por aqui. Até o próximo!
Peace!

Chrystian C. Rosa

--

--