Melhorando a performance nos testes de integração com PHP/Laravel
Published: 2023-03-05 17:54:05

Conforme nossa aplicação vai crescendo, o número de migrations também cresce. Em alguns casos, nos testes de integração optamos por ter toda a estrutura do banco sendo testada, para isso criamos e apagamos o banco em cada teste. Porém com o tempo essa tarefa se torna onerosa e passa a impactar na longa demora do processo do CI da aplicação, gerando um desconforto, principalmente quando temos um Hotfix que precisa subir o mais rápido possível.

Geralmente é utilizado nos testes a trait `RefreshDatabase`, vamos ver o que essa trait faz.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/949m82kxmaspq7a2vkrc.png)

Vejam que na trait é utilizado o comando `migrate:fresh`, esse comando desfaz todo o banco e cria ele novamente, isso é feito a cada stack de teste. 
Desenvolvi um projeto simples para analisarmos o tempo gasto usando a trait `RefreshDatabase`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9kz6eevtd84cyc1n3h7.png)

Com 11 testes rodados demoramos 1.86s, parece tranquilo, mas nossas migrations não mudam certo? principalmente com um projeto já em produção, então porque precisamos sempre recriar o banco em cada teste? 

Vamos tentar uma outra abordagem, no Laravel temos uma outra trait chamada `DatabaseTransactions`, vamos da uma olhada nela.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5nz4kzb7esooyedo6jj.png)

Reparem que nessa trait temos algo diferente, é criada uma transação do banco no inicio do teste e após a conclusão é dado um rollback, vamos substituir ela e ver no que dar. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npnssq4igf7ll2zvk0np.png)

Oops temos um erro, para resolver esse problema teremos que executar nossas migrations antes dos nossos testes, podemos utilizar a configuração de bootstrap do phpunit para isso, por padrão essa configuração aponta para o arquivo Autoload da nossa vendor.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/di70x06fynil1nxrhitz.png)  
Para mais informações sobre o bootstrap do phpunit clique [aqui](https://docs.phpunit.de/en/9.5/configuration.html#the-bootstrap-attribute)

Vamos criar um arquivo bootstrap customizado.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgdv6ecmzlt60xcfz2q0.png)

No arquivo inicializamos o bootstrap da aplicação e no final temos o comando `migrate:fresh`, esse comando vai ser rodado somente uma vez na inicialização dos testes, Agora vamos ajustar o caminho do bootstrap na configuração do phpunit.xml, apontando para o novo arquivo e rodar novamente os testes. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/440toj5veuj20sv5viqy.png)

**Conclusão**

O que vemos é uma diferença absurda de performance nos nossos testes. Para um projeto muito grande com várias migrations utilizar a trait `DatabaseTransactions` deixam os testes bem mais performáticos, segue aqui alguns exemplos do projeto desenvolvido nessa demonstração no meu Github, com a branch utilizando [RefreshDatabase](https://github.com/tiagobrunoBFR/fast-tests) e com [DatabaseTransaction](https://github.com/tiagobrunoBFR/fast-tests/tree/test/add-database-transactions), Espero que esse post seja útil.