escrito por Wilson Marcos Ferreira Correa
4 minutos de leitura
Neste artigo, vamos mostrar como acelerar o desenvolvimento de testes de integração utilizando o GitHub Copilot. Essa ferramenta de inteligência artificial auxilia desenvolvedores na geração de código a partir do contexto, sendo extremamente útil para acelerar a criação de testes, além de aumentar a produtividade e a consistência. Para a prática, usaremos Spring Boot na construção de um serviço REST, Spring Data JPA para a interação com o banco de dados PostgreSQL e Testcontainers para simular o ambiente de banco durante os testes.
Vamos construir um micro serviço REST simples usando Spring Boot, com um repositório de dados utilizando Spring Data JPA e PostgreSQL como banco de dados. Em seguida, criaremos testes de integração para garantir que nosso serviço e repositório funcionem corretamente.
Estrutura do Projeto
Primeiramente, crie um novo projeto Spring Boot utilizando o Spring Initializr, selecionando as dependências: Spring Web
Adicione também as dependências necessárias no build.gradle:
Configure o acesso ao banco de dados no arquivo src/main/resources/application-local.yml:
Vamos criar um arquivo de regras para que o Copilot possa seguir alguns padrões e que possa gerar o código deste serviço de exemplo. Crie uma pasta com nome GitHub nas pasta base desse projeto. Em seguida, crie um arquivo chamado copilot-instructions.md dentro desta nova pasta. Esse arquivo é muito útil para que o Copilot siga os padrões que desejar e consequentemente ter o código gerado de maneira coerente entre as várias implementações dentro do projeto. Vamos utilizar as instruções abaixo para nosso teste:
Acesse o Copilot e altere para o modo Agent, no prompt solicitaremos ao Copilot que gere a estrutura de tabelas que vamos utilizar.
Setup this project to support flyway migrations and generate the initial script to create a procuts schema and a products table with the following fields: id (UUID) as primary key. name (varchar(100)) set this one as unique key. id (UUID) as primary key. name (varchar(100)) set this one as unique key. Setup the configuration file application-local.yml to support jpa defining PostgreSQLDialect and datasource configurations.
Também no modo Agent, vamos solicitar a geração do código fonte.
Create a product package and the packages entrypoint, domain and infrastructure packages inside. Generate a CRUD for the product table exposing a rest api for the product operations.
Ao final teremos o código fonte gerado com as camadas solicitadas e os endpoints REST que vamos utilizar no teste de integração.
Testcontainers para Java é uma biblioteca que oferece suporte a testes JUnit, fornecendo instâncias simplificadas de bancos de dados conhecidos e diversas outras ferramentas que possam ser executadas em um container Docker. Vamos solicitar ao Copilot que utilize o framework Testcontainers para a geração dos testes de integração e vamos solicitar que sejam gerados os testes de integração para o controller ProductController que foi gerado anteriormente. Vamos solicitar também que sejam gerados os testes unitários para este projeto.
Setup this project to support testcontainers framework. Generate integration tests for the controller ProductController. Generate unit tests
Os testes foram gerados e o Copilot seguiu corretamente as instruções que colocamos no arquivo copilot-instructions.md.
Ao executar o teste teremos os seguintes passos:
O arquivo gerado, ProductControllerIntegrationTest possui a configuração base para o Postgres e o ContextInitializer. Esse trecho poderia estar em uma classe base para que possa ser reaproveitado em outros testes de integração que possam ser gerados no futuro. Para deixar mais organizado, vamos solicitar ao Copilot que faça a extração das configurações comuns em uma classe base e faça a alteração do ProductControllerIntegrationTest para que utilize a classe base gerada como herança.
Extract ApplicationContextInitializer from ProductControllerIntegrationTest to a Base class to be reused to new integration classes in the future. Move the class annotations from ProductControllerIntegrationTest to the new base class once it will be reused. Refactor ProductControllerIntegrationTest to extend this new base class.
O Copilot foi capaz de extrair o conteúdo comum em uma classe chamada BaseIntegrationTest e fez as alterações necessárias na classe ProductControllerIntegrationTest, removendo o conteúdo presente na classe base e fazendo a herança.
O uso do tipo Record no java pode gerar problemas onde o Copilot eventualmente gera um get para acesso aos atributos. Para os testes de integração utilizamos o TestRestTemplate. Ao mapear a porta para realizar a chamada http o Copilot faz o import incorreto do LocalServerPort.Foi necessário corrigir o pacote informado de import org.springframework.boot.web.server.LocalServerPort; para import org.springframework.boot.test.web.server.LocalServerPort; Pouco contexto gera resultados aleatórios. Procure dar a maior quantidade de informações possível ao Copilot para ter um resultado melhor.
O Copilot é um exemplo prático de como os LLM´s estão mudando a maneira como estamos escrevendo código. A ferramenta demonstrou ser capaz de gerar código e fazer melhorias em um código existente. Foi capaz também de gerar os testes unitários rapidamente. Com exceção do setup inicial do projeto Springboot, praticamente todo este exemplo foi criado utilizando o Copilot.
Em projetos existentes é possível solicitar ao Copilot que faça a análise do projeto e preencha o arquivo de instructions acelerando a adoção da ferramenta dentro dos padrões que já utiliza. É possível também dizer ao Copilot exemplos de implementação para que ele siga os padrões utilizados no exemplo informado. Testes mais complexos requerem mais contexto, quanto mais informação passada ao Copilot, mais completo e assertivo será o código gerado. Mesmo em testes unitários pode ser necessário dar instruções específicas para a geração de determinados testes, obtendo uma melhor cobertura e assertividade.
Durante o desenvolvimento dos testes, o GitHub Copilot pode ser utilizado para acelerar a escrita de código. Ele pode sugerir implementações completas de métodos e até trechos de configuração. Por exemplo, ao começar a escrever um teste para a criação de um produto, o Copilot pode sugerir automaticamente o código do teste, o que acelera consideravelmente o processo, deixando o desenvolvedor mais focado em regras complexas.
Clique aqui para acessar o código fonte desse projeto.