Melhorando seus Testes com GRAMÁTICA
Tags: testing, php, braziliandevs, programming
Published: 2021-11-24 14:30:47

## Prólogo

Há tempos eu venho fazendo code reviews em repositórios dos meus viewers, que pedem esse CR em live etc e eu fico muito atento as boas práticas mas eu vejo que algo muito comum entre essas amostras é como falta alguns entendimentos para nomes de métodos ou até mesmo as classes.

Como entender o que o método **handle** faz no **AppRepository**? Ou o que o teste **test_user_fails** faz na suite **UserCommandsTest**? Muitas vezes falta descrição ou objetividade no que é escrito te faz perder muito tempo tentando entender como funciona ou qual deveria ser o comportamento correto daquele bloco de código.

Há muito tempo essa prática de não ser auto descritivo vem sendo sustentada pelos desenvolvedores do mundo a fora e você pode entender que quando uma empresa te pede para corrigir esse tipo de coisa, para ser mais assertivo em como deixar uma função legível, é porquê essa empresa se preocupa mais com a QUALIDADE do código entregue do que com qualquer outra coisa.

Existem muitos pontos que dizem se um código é limpo ou não, mas um deles certamente é a clareza de como você escreve seus métodos ou documentação.

## Suites de Testes

O cenário mais comum onde devs vem pecando cada vez mais em descrições que não descrevem nada é no PIOR LUGAR pra isso acontecer: SUITES DE FUCKING TESTES!

Cara, você ter uma suíte com 103782183129 testes que não são auto descritivos é um tiro no pé IMENSO do ponto de vista de quem vai dar manutenção nisso no futuro. Testes devem cobrir cenários especificos, porém, se você não CONTAR ou especificar os comportamentos no nome da função, já não vai servir de muita coisa. Vamos pra um exemplo: 

Peguei um código pra revisar onde o método deveria checar se uma transação estava sendo feita para o mesmo usuário e estava sendo escrito assim: 
```php
public function test_payer_and_payee_equals();

it("payer and payee equals");
```

Quando eu li isso, inicialmente eu fiquei confuso porquê pra mim na primeira interpretação até ler o código, deveria ser pra checar se os usuários são iguais porém no código eles NÃO deveriam ser iguais. 

Agora vamos entender algumas palavrinhas que podem de fato ajudar a ter um melhor entendimento para a criação de sentenças de testes:

* Can = Usado quando o usuário DEVE ter aquele comportamento e é um teste não tem exceções (fluxo de como deveria funcionar)
* Should = Usado quando o usuário DEVERIA ter aquele comportamento e é um teste que vai cair em alguma exceção (fluxo de como deveria chegar na exceção)
* Should NOT = Usado quando o usuário não deveria ter algum comportamento e é um teste que vai cair em alguma exceção (fluxo de como deveria chegar na exceção)


Se eu fosse reescrever o nome da função pra ser algo mais claro, ficaria assim: 

```php
public function test_payer_and_payee_should_not_be_the_same();

it("payer and payee should not be the same");
```

ou

```php
public function test_user_should_not_send_money_to_his_own_account();

it("user should not send money to his own account");
```

Ficou bem mais descritivo né? O esperado de um teste é que o nome da função seja a descrição do que deve acontecer ali dentro. Agora vamos pro segundo exemplo:

```php
public function test_value_is_greather_than_zero();

it("value is greather than zero");
```

Esse aqui ficou bem confuso... O nome da suite é **TransactionControllerTest** então você consegue assumir algumas coisas vendo o nome desse teste, porém, você assumir algo quer dizer que o teste não diz o que faz e isso é um problema se você tiver de refatorar ele lá na frente. 

* O que eu interpretei: o valor (que eu não sei do que exatamente) tem/deve que ser é maior que zero.
* O que deveria ser: o valor da transação deve ser maior que zero.

Agora reescrevendo essa função temos as possibilidades:

```php
public function test_user_should_transfer_an_amount_greather_than_zero();

it("user should transfer an amount greather than zero");
```

ou 

```php
public function test_transaction_amount_should_be_greather_than_zero();

it("transaction amount should be greather than zero");
```

Esses cenários até o momento não envolveram a palavra "should" e "not" que especificam que os cenários deverão cair em exceções. 

Agora vamos para um cenário positivo onde nada daria erro contemplando a mesma suíte de testes: 


```php
public function test_balance_payee_is_ok_after_transaction();

it("balance payee is ok after transaction");
```

Eu vi que é o único teste que retorna 201, então eu já entendi que ele vai pelo lado certo da coisa. Porém, ainda não achei o nome do teste descritivo ao ponto de saber o que tá rolando.

Você citar um comportamento do TESTE no nome não fica tão legal, afinal, o seu teste precisa garantir que o valor da carteira do pagador vai estar OK, certo?! Isso é pra dentro do código, não pro nome.

O que poderia fazer para melhorar esse cenário:

```php
public function test_user_can_create_a_new_deposit();
public function test_user_can_create_a_new_withdraw();
public function test_user_can_create_a_new_transaction();

it("User can create a new deposit");
it("User can create a new withdraw");
it("User can create a new transaction");
```

Mais assertivo que isso eu creio que seja impossível. Usando o **can** nós estamos AFIRMANDO que o retorno tem que ser algo positivo, já que o usuário PODE fazer aquela ação. 

Espero que você tenha gostado da ideia proposta no post, não esqueça de deixar de compartilhar nas redes sociais e deixar o like aqui na plataforma!