Conteúdos

Iniciando testes com a sua equipe em código legado

Pode ser realmente complicado começar a escrever teste em uma base de código legada. São diversos desafios quando você tem uma equipe que nunca escreveu testes, ou que se frustaram em tentativas anteriores. Esse artigo traz algumas táticas para lidar com código não testado.

Por que testar

Talvez a parte mais complicada de iniciar a escrita de testes, quando se tem uma base legada, é entender por que eu tenho que testar? E na real você não tem que testar. Os testes vem para facilitar a manutenção do seu código, bem como “documentar” já que de certo modo nos testes você tem o comportamento esperado do seu sistema.

Só um parenteses
Programação orientada a objeto não tem a ver somente com comportamento, que é a forma como o seu sistema lida com entrada e saída de dados, mas também com relacionamentos (talvez o mais importante), que são as formas como as suas classes interagem. Testes unitários também ajudam a validar e documentar isso.

Ter uma cobertura de testes alta, ajuda a lidar com futuras atualizações, seja de versões do PHP, de bibliotecas ou de seu próprio código.

Estratégias possíveis

Uma boa forma de começar é gerar o relatório de cobertura de testes no projeto. Com o PHPUnit você pode usar o comando phpunit --coverage-html [caminho_relatorio], onde [caminho_relatorio] é a pasta onde o PHPUnit irá colocar o relatório.

Exemplo de code coverage

Exemplo de code coverage

Com esse relatório em mãos você tem duas abordagens:

  1. Atacar as classes maiores
  2. Atacar as classes mais críticas do sistema

Em qualquer das duas abordagens, comece pequeno. Pegue uma classe grande, caso tenha escolhido a primeira opção, e faça testes de um método por vez.

Dica
Aproveite esse momento para rever o tamanho das suas classes e métodos. Crie um teste para um método gigante. Assim que ele estiver rodando, quebre esse método em partes menores, e veja se os testes continuam passando.

Perceba que conforme for escrevendo mais código, ficará mais fácil de refatorar o seu código, e verificar possíveis cenários de bugs.

Não corra atrás do 100%
O relatório de cobertura te ajuda a identificar as classes que você precisa testar. Mas atingir 100% de cobertura de código é algo contraproducente. Isso por que ao buscar 100% você acabará criando testes que não testam nada efetivamente.

Como escrever testes

Seja claro na intenção do teste

Dê nomes informativos para classes e métodos de testes:

  • Para testes unitários use o nome da classe junto com o sufixo Test e siga o mesmo esquema de pastas: App\Models\UsuarioModel -> Tests\Models\UsuarioModel
  • Ao nomear os métodos de testes, informe o que está sendo testado: testAddNewUser e testAddNewUserInvalidShouldThrowException são bons nomes.
  • Não use números mágicos nos testes (melhor não usar números mágicos nunca):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

/**
 * Exemplo confuso, não sei quais são os 
 * parametros do método add e nem o que o número 2 representa
 */
public function testAddNewUser(): void
{
    self::assertEquals(2, $this->userService->add('João', '123'));
}

/**
 * Por mais que parece "verboso", a criação das variáveis 
 * deixa o código mais simples de compreender
 */
public function testAddNewUser(): void
{
    $name = 'João';
    $password = '123';
    $idUser = $this->userService->add($name, $password);
    $expectedIdUser = 2;

    self::assertEquals($expectedIdUser, $idUser);
}

Escreva testes para todo novo código

Sempre que precisar alterar qualquer coisa no código, seja adicionar novas funcionalidades ou corrigindo coisas, escreva um teste para isso.

Crie testes para cenários de bugs

Digamos que você vai corrigir um bug no código, que caso o usuário informe um email inválido, isso quebra o sistema. Crie testes específicos para esses cenários:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php

/**
 * Para esses testes de cenários de bugs, é interessante colocar o 
 * número da task do seu gerenciador de ocorrências (Jira, Github issues...)
 */
class UserBug24Test
{
  public function testIfInvalidEmailShouldPass(): void
  {
    $name = 'João';
    $password = '123';
    $invalidEmail = 'joao@gmail';
    $idUser = $this->userService->add($name, $password, $invalidEmail);
    $expectedIdUser = 2;

    self::assertEquals($expectedIdUser, $idUser);
  }
}

Isso facilitará o acompanhamento dos bugs surgidos no seu sistema, e evitará que esse bug volte no futuro.

Essas são algumas coisas que aprendi ao começar a escrever testes em sistemas legados. Seja persistente, no começo pode parecer que está atrasando as entregas, mas a longo prazo, você vai ter um ganho ao não precisar dar rollbacks nos deploys por erros que deixou passar.