Anteriormente, passamos pela atividade de configuração do ambiente e agora temos o projeto importado no IntelliJ. Conforme mencionado, nesse curso, trabalharemos no projeto de uma aplicação em Java, mas independentemente da linguagem de programação utilizada, focaremos no ChatGPT e em como ele pode auxiliar em programação.
Como precisávamos de um projeto, ele foi escrito em Java, mas poderia ser em qualquer outra linguagem, então não precisamos nos preocupar com esse detalhe. Nosso foco é saber como utilizar o ChatGPT para ajudar no dia a dia com programação.
Conhecendo o projeto
Com o projeto aberto no IntelliJ, vamos entendê-lo um pouco melhor antes de começar com o ChatGPT. Primeiramente, vamos executar a aplicação e fazer um teste.
Vimos anteriormente que o projeto se trata de uma API Rest. Para executá-lo, vamos acessar o painel lateral esquerdo da interface e expandir o projeto "vollmed-api". Encontraremos a pasta "src", contendo o diretório "main", que contém o diretório "java", onde está armazenado todo o código-fonte do projeto.
Entre os arquivos, temos a classe ApiApplication.java. Vamos abri-la:
package med.voll.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
Na linha de código 7, onde está a classe ApiApplication, há um ícone de play na lateral esquerda. Vamos clicar sobre ele e selecionar a opção "Run 'ApiApplication.main()'".
Então, temos uma classe com o método main() que irá executar a aplicação e carregar toda a infraestrutura da nossa API.
Após executar, será retornado um log na aba "Run", indicando o que está sendo feito. Trata-se do log das bibliotecas e frameworks do mundo Java.
Ao final do log, é importante aparecer a seguinte linha:
Tomcat started on port(s): 8080 (http) with context path ''
Isso indica que o servidor inicializou na porta 8080. Uma vez inicializado o projeto, já podemos disparar requisições para a API usando o endereço "localhost:8080".
As requisições também foram disponibilizadas para fazermos os testes.
Por ser uma API, não temos tela de interface, então testaremos por meio de algum aplicativo de testes de API. Nesse caso, o Postman.
O instrutor já importou as coleções com as requisições. São elas:
- Agenda Consultas
- CRUD Médicos
- CRUD Pacientes
- Relatórios
Estamos trabalhando no projeto de uma clínica médica. Na coleção de CRUD de médicos, temos as requisições referentes às funcionalidades de médicos, que são: "Cadastrar médico", "Listar médicos", "Detalhar médico", "Atualizar médico", e "Excluir médico".
Além disso, temos um CRUD de pacientes, com as mesmas funcionalidades; uma parte de relatórios, que contém somente 1 relatório; e a parte de agendamento de consultas, contendo duas requisições.
Essa é a aplicação e suas funcionalidades!
Identificando bugs
No Postman, conseguimos simular e testar a API.
Vamos começar, por exemplo, com o teste de cadastro de paciente. Para isso, acessamos a coleção "CRUD Pacientes" e abrimos a requisição do tipo POST "Cadastrar paciente".
{
"nome": "Paciente 1",
"email": "[email protected]",
"cpf": "123.123.123-00",
"telefone": "61999998888",
"endereco": {
"logradouro": "Rua",
"bairro": "Bairro",
"cep": "12345678",
"cidade": "Cidade",
"uf": "UF",
"numero": "1",
"complemento": "Complemento"
}
}
Na seção direita do Postman, são exibidos os detalhes da requisição. Na barra de endereços, temos o "localhost:8080/pacientes", e no corpo da requisição (aba "Body"), temos um JSON representando os dados que serão enviados para a aplicação.
Estamos basicamente cadastrando um novo paciente, então temos campos como nome, email, cpf, telefone, e os dados de endereco.
Vamos clicar no botão azul "Send", à direita da barra de endereço, para disparar a requisição. Feito isso, será aberta uma barra inferior contendo a resposta devolvida pelo servidor, nesse caso, "201 Created".
Será devolvido também o corpo da resposta. No caso, a API devolveu um JSON com os dados do paciente recém-cadastrado:
{
"id": 1,
"ativo": true,
"nome": "Paciente 1",
"email": "[email protected]",
"cpf": "123.123.123-00",
"telefone": "61999998888",
"endereco": {
"logradouro": "Rua",
"bairro": "Bairro",
"cep": "12345678",
"numero": "1",
"complemento": null,
"cidade": "Cidade",
"uf": "UF"
}
}
Nesse momento, já identificamos um problema: observando os dados cadastrados no corpo da requisição, preenchemos todas as informações; porém, no retorno do servidor, o campo complemento do endereço foi devolvido com o valor null.
Então, temos um bug no nosso código. Podemos usar o ChatGPT para identificar onde ele está!
Com a ferramenta aberta no navegador, vamos utilizá-la para resolver o problema. O ideal é fazer uma pergunta bastante objetiva e detalhada para o ChatGPT, para que ele consiga nos auxiliar da melhor maneira possível.
Podemos explicar o contexto e solicitar ajuda da seguinte forma:
Tenho uma aplicação desenvolvida em Java, utilizando o framework Spring Boot, com uma funcionalidade de cadastro de pacientes que está com um bug. Poderia me auxiliar na detecção desse bug?
Geralmente, o ChatGPT é bastante simpático e aberto, então foi obtida a mensagem abaixo:
Claro, ficarei feliz em ajudar você a encontrar o bug em sua aplicação Java com o Spring Boot. Por favor, forneça mais informações sobre o problema em questão. Descreva o comportamento indesejado que está ocorrendo e inclua qualquer mensagem de erro ou trecho de código relevante. Quanto mais detalhes você puder fornecer, melhor será a minha compreensão do problema e mais precisa será minha assistência.
Agora, sim, forneceremos os detalhes. Começamos com o contexto inicial, então nessa segunda etapa já podemos colar o código e pedir para que a ferramenta tente encontrar o erro.
Retornando ao IntelliJ, vamos buscar pelo método de cadastro de paciente. Ele está localizado na linha de código 29 do arquivo PacienteController.java:
@PostMapping
@Transactional
public ResponseEntity<DadosDetalhamentoPaciente> cadastrar(@RequestBody @Valid DadosCadastroPaciente dados, UriComponentsBuilder uriBuilder) {
var detalhesPaciente = service.cadastrar(dados);
var uri = uriBuilder.path("/pacientes/{id}").buildAndExpand(detalhesPaciente.id()).toUri();
return ResponseEntity.created(uri).body(detalhesPaciente);
}
Com o código copiado, vamos retornar ao ChatGPT e colar o trecho no campo de perguntas. Em seguida, vamos pressionar "Shift" e teclar "Enter" para dar um espaço após o código.
Além do método, precisamos levar também o restante das classes do projeto, para que o ChatGPT possa analisar. O método cadastrar() recebe como parâmetro a classe DadosCadastroPaciente. Ela é muito importante, pois o ChatGPT precisará analisá-la para tentar identificar o problema.
Então, vamos copiar todo o código da classe, presente no arquivo DadosCadastroPaciente.java, e colar logo abaixo do método no campo da pergunta.
public record DadosCadastroPaciente(
@NotBlank
String nome,
@NotBlank
@Email
String email,
@NotBlank
@Pattern(regexp = "^(\\(\\d{2}\\)|\\d{2})\\s?\\d{4,5}-?\\d{4}$")
String telefone,
@NotBlank
@Pattern(regexp = "\\d{3}\\.?\\d{3}\\.?\\d{3}\\-?\\d{2}")
String cpf,
@NotNull @Valid
DadosEndereco endereco) {
}
A classe DadosCadastroPaciente é composta por outra classe, a DadosEndereco, localizada no arquivo DadosEndereco.java. Também iremos colá-la no ChatGPT.
public record DadosEndereco(
@NotBlank
String logradouro,
@NotBlank
String bairro,
@NotBlank
@Pattern(regexp = "\\d{8}")
String cep,
@NotBlank
String cidade,
@NotBlank
String uf,
String complemento,
String numero) {
}
Com essas 3 classes, a ferramenta deve conseguir identificar o bug. Caso contrário, ela irá solicitar mais códigos.
A princípio, obtivemos a seguinte resposta:
Obrigado por compartilhar o código. Vou analisar e tentar identificar possíveis problemas ou bugs.
À primeira vista, o código parece estar correto. No entanto, alguns detalhes estão faltando para entender completamente o contexto e a natureza do bug que você está enfrentando.
- Você poderia fornecer mais informaçõe sobre o comportamento indesejado ou o erro específico que está ocorrendo quando você tenta cadastrar um paciente? Isso ajudará a direcionar minha análise.
- Além disso, você pode fornecer o código da classe
service onde o método cadastrar está implementado? Isso me ajudaria a entender melhor o fluxo de trabalho e verificar se há algum problema nessa parte do código. - Certifique-se de que todas as dependências necessárias estão corretamente configuradas no arquivo
pom.xml. Se houver algum problema de configuração ou incompatibilidade entre as versões das bibliotecas, isso pode causar erros ou comportamento indesejado.
Por enquanto, com base no código fornecido, não parece haver erros óbvios. O método cadastrar no controlador Spring Boot parece receber dados de cadastro de pacientes, validar as entradas usando as anotações do Bean Validation e, em seguida, chamar o método cadastrar no serviço correspondente. O resultado desse cadastro é retornado como uma resposta HTTP 201 (Created) com o URI do paciente recém-criado.
Por favor, forneça as informações adicionais solicitadas para que eu possa ajudá-lo de maneira mais efetiva a resolver o problema.
Conforme solicitado pelo ChatGPT, vamos informar onde está o bug que buscamos:
O bug está no campo complemento do endereço, que está sendo enviado no JSON, porém está sendo salvo como null.
Com essa informação, a ferramenta encontra o problema:
Obrigado por fornecer mais informações sobre o bug. Com base na sua descrição, o problema parece estar relacionado ao campo "complemento" do objeto DadosEndereco não sendo persistido corretamente. Vamos verificar algumas possíveis causas:
- Certifique-se de que o campo "complemento" esteja sendo enviado corretamente no JSON da requisição. Verifique se o nome do campo no JSON está correspondendo exatamente ao nome do atributo na classe
DadosEndereco. - Verifique se o campo "complemento" está configurado corretamente como um parâmetro opcional no construtor do
DadosEndereco e se está sendo atribuído corretamente ao atributo correspondente. - Verifique se a tabela do banco de dados que armazena os dados dos pacientes possui uma coluna correspondente ao campo "complemento". Se não houver uma coluna para o campo "complemento", pode ser necessário atualizar o esquema do banco de dados para refletir essa alteração.
- Certifique-se de que o mapeamento do objeto
DadosEndereco para a tabela do banco de dados esteja configurado corretamente. Verifique se o mapeamento das colunas está alinhado com os nomes e tipos dos atributos da classe DadosEndereco.
Se nenhuma dessas sugestões resolver o problema, seria útil fornecer o código da classe service onde o método cadastrar está implementado. Isso ajudaria a identificar se há alguma lógica adicional que possa estar causando o comportamento indesejado.
Além disso, verificar os logs e possíveis mensagens de erro relacionados à persistência dos dados também pode ser útil para entender melhor o problema específico que você está enfrentando.
O ChatGPT informa que, com base na informação sobre o bug, foi identificado que o campo complemento está no objeto DadosEndereco, então vamos verificar esse objeto específico no IntelliJ.
No arquivo DadosEndereco.java, temos a classe DadosEndereco, que representa o JSON enviado no Postman. Retornando ao Postman, temos o envio do JSON como requisição, contendo os dados do paciente. Porém, dentro dele há outro objeto que representa os dados do endereço.
"endereco": {
"logradouro": "Rua",
"bairro": "Bairro",
"cep": "12345678",
"cidade": "Cidade",
"uf": "UF",
"numero": "1",
"complemento": "Complemento"
}
Esse trecho específico, contendo os dados do endereço, está sendo mapeado para a classe DadosEndereco. Mas em algum lugar desse código está o problema, justamente no caso do complemento. Como enviamos um texto como complemento e o retorno foi nulo, esse campo não foi enviado ou não chegou corretamente.
Analisando esse trecho no código do IntelliJ, o erro está na digitação da String, que deveria ser complemento e está escrita como complemeto. No código Java, o nome do campo está diferente do nome enviado no JSON, porém eles precisam ser iguais.
Com o arquivo DadosEndereco.java aberto, vamos clicar com o botão direito sobre complemeto e ir até "Refactor > Rename…". Será aberta uma janela onde iremos renomear a String como para complemento. Dessa forma, a renomeação irá acontecer também no restante do projeto.
Vamos verificar a aba "Run". Se a configuração estiver correta, ao mexer no código, o projeto será reinicializado.
Para conferir se a configuração está correta, podemos usar o atalho "Ctrl + Alt + S" para abrir a janela "Settings" e acessar "Build, Execution, Deployment > Compiler". A opção "Build project automatically" deve estar ativada.
Finalizada a mudança, vamos retornar o Postman. Agora, precisaremos cadastrar outro paciente, pois há uma regra no projeto que não nos permite cadastrar dois paciente com o mesmo nome, email e CPF. Então, cadastraremos o seguinte:
{
"nome": "Paciente 2",
"email": "[email protected]",
"cpf": "333.333.333-00",
"telefone": "61999998888",
"endereco": {
"logradouro": "Rua",
"bairro": "Bairro",
"cep": "12345678",
"cidade": "Cidade",
"uf": "UF",
"numero": "1",
"complemento": "Complemento"
}
}
Note que estamos enviando o complemento normalmente, da mesma forma que fizemos antes. Disparada a requisição, teremos o seguinte retorno:
{
"id": 2,
"ativo": true,
"nome": "Paciente 2",
"email": "[email protected]",
"cpf": "333.333.333-00",
"telefone": "61999998888",
"endereco": {
"logradouro": "Rua",
"bairro": "Bairro",
"cep": "12345678",
"numero": "1",
"complemento": "Complemento",
"cidade": "Cidade",
"uf": "UF"
}
}
Agora o complemento foi salvo corretamente!
Perceba que usamos o ChatGPT para nos auxiliar, indicando o problema e enviando o código necessário para identificar o bug.
Eventualmente, a ferramenta passará a perceber que existe algum erro de digitação. Mas nem sempre ela conseguirá detectar logo a princípio. Nesse caso, podemos dar dicas, detalhar melhor, colar novamente apenas trechos específicos do código, entre outras ações.
Fica uma lição importante: o ChatGPT é uma ferramenta que irá nos auxiliar, não nos substituir. Além disso, a ferramenta comete erros.
Nem sempre a resposta será a melhor possível, e nem sempre será retornado um código correto, então cabe a nós avaliarmos a resposta e usar as dicas dadas pela IA, em vez de simplesmente copiar e colar qualquer código trazido como solução.
Conclusão
Esse é um dos usos possíveis do ChatGPT em programação: identificação de bugs. Se você tem um projeto (independentemente da linguagem de programação, das tecnologias e dos frameworks), existe algum bug, e está complicado encontrar a origem apenas analisando o código, ou deseja agilizar esse processo, basta perguntar para o ChatGPT!
Primeiro, tente explicar a tecnologia, a funcionalidade, e o bug. Em seguida, você pode colar o código para que a ferramenta faça sua análise. Talvez seja apontado diretamente o problema, ou talvez sejam dadas dicas, como aconteceu no nosso caso.
Podemos usar o ChatGPT para muitas outras coisas. Veremos na sequência!