Introdução aos testes com o Gemini Code Assist

1. Introdução

Neste laboratório, você vai usar o Gemini Code Assist, um colaborador com tecnologia de IA do Google Cloud, para adicionar testes a um aplicativo da web Python e encontrar e corrigir erros nesse aplicativo expostos pelos testes. Em seguida, você vai usar o Code Assist para criar testes de novas funcionalidades e gerar código para passar nesses testes e estender o app.

O que você vai fazer…

  • Você vai usar o editor do Cloud Shell para baixar o código de um aplicativo da Web.
  • Você vai usar o chat do Gemini Code Assist no editor do Cloud Shell para fazer perguntas gerais sobre o Google Cloud.
  • Você vai usar a assistência de código inline do Gemini Code Assist no editor do Cloud Shell para gerar e executar testes, encontrar e corrigir erros e, em seguida, estender a funcionalidade do aplicativo.

O que você vai aprender…

  • Como usar o Gemini Code Assist para várias tarefas de desenvolvimento, como geração de testes e de código.
  • Como usar o Gemini Code Assist para aprender sobre o Google Cloud.

O que é necessário…

  • Navegador da Web Google Chrome
  • Uma conta do Gmail
  • Um projeto do Cloud com faturamento ativado
  • O Gemini Code Assist está ativado para seu projeto do Cloud

Este laboratório é voltado para desenvolvedores com todos os níveis de conhecimento, inclusive iniciantes. O aplicativo de amostra está na linguagem Python, mas você não precisa conhecer esse tipo de programação para entender o que está acontecendo. Nosso foco será apresentar os recursos do Gemini Code Assist para desenvolvedores.

2. Configuração

Você já precisa ter um projeto do Cloud com o faturamento ativado para usar neste laboratório. Agora ative a API Gemini no projeto do Google Cloud. Siga estas etapas:

  1. Acesse https://console.cloud.google.com e confira se você selecionou o projeto do Google Cloud com que vai trabalhar neste laboratório. Clique no ícone do Gemini no canto superior direito.

GeminiBanner.png

  1. A janela do Gemini para console do Cloud vai abrir no lado direito do console. Clique no botão Ativar, se ele aparecer abaixo. Se o botão Ativar não aparecer e, em vez disso, uma interface do chat for mostrada, você já ativou o Gemini no Cloud para o projeto e pode ir direto para a próxima etapa.

GeminiApiEnable.png

  1. Depois da ativação, é possível testar o Gemini com uma ou duas consultas. Alguns exemplos de consultas são mostrados, mas é possível tentar algo como O que é o Cloud Run?

GeminiChatWindow.png

O Code Assist vai responder à pergunta. Clique no ícone f68286b2b2ea5c0a.png no canto superior direito para fechar a janela de chat do Code Assist.

Ativar o Gemini no editor do Cloud Shell

O Gemini Code Assist está disponível e funciona de maneira semelhante em vários ambientes de desenvolvimento integrado conhecidos. Neste codelab, você vai usar o Google Cloud Shell Editor, que é executado completamente no seu navegador da Web. É necessário ativar e configurar o Gemini no editor do Cloud Shell. Para isso, siga as etapas abaixo:

  1. Inicie o Cloud Shell com o ícone mostrado abaixo. Esse processo pode levar um ou dois minutos.

72dc3df7b007fcde.png

  1. Clique no botão Editor ou Abrir editor (conforme o caso) e aguarde até que o editor do Cloud Shell apareça. Se estiver disponível, clique no botão Conheça o novo editor.

CloudShellEditor.png

  1. Clique no botão Cloud Code – Fazer login na barra de status inferior, conforme mostrado. Autorize o plug-in conforme instruído. Se a barra de status mostrar Cloud Code – sem projeto, clique na opção e escolha o projeto do Google Cloud com que você quer trabalhar na lista.

CloudCodeSignIn.png

  1. Se o ícone do Gemini não aparecer na barra de status na parte inferior direita, ative o Gemini no Cloud Code. No entanto, antes de tudo, confira se o Gemini (anteriormente conhecido como Duet AI para desenvolvedores) está ativado no ambiente de desenvolvimento integrado (IDE). Para isso, acesse Extensão do Cloud Code → Configurações e insira o texto Duet AI: Ativar, conforme mostrado abaixo. Confira se a caixa de seleção está marcada. Recarregue o ambiente de desenvolvimento integrado. Isso ativa o Gemini no Cloud Code, e a barra de status do Gemini aparece no seu ambiente de desenvolvimento integrado.

EnableDuetAiSetting.png

  1. Clique no botão Gemini no canto inferior direito, conforme mostrado, e selecione o projeto correto do Google Cloud em que a API Cloud AI Companion foi ativada.

GeminiSelectGoogleCloudProject.png

  1. Depois de selecionar o seu projeto na nuvem do Google Cloud, confira se a mensagem de status do Cloud Code aparece na barra de status. Analise também se o Gemini está ativado à direita, na barra de status, conforme mostrado abaixo:

GeminiEnabledStatusBar.png

O Gemini Code Assist está pronto para uso.

3. Baixar e examinar o aplicativo

Na janela do terminal, execute o comando para clonar o repositório com o código inicial e mude para o novo diretório. Se a janela do terminal não estiver mais aberta, clique no botão Terminal ou Abrir terminal para restaurá-la:

git clone https://github.com/GoogleCloudPlatform/testing-with-duet-ai-codelab.git
cd testing-with-duet-ai-codelab

Abra main.py no editor e clique no ícone de conversa no Gemini à esquerda para abrir a janela conversa no Gemini. Essa janela do Gemini Chat está no ambiente de desenvolvimento integrado e tem o código disponível como contexto para discussão. Digite o comando Explique isso e confira a resposta:

GeminiChatExplainThis.png

Role a janela de chat para ver a resposta completa. A explicação diz que podemos executar esse programa localmente com o comando python3 main.py na janela do terminal.

4. Executar no local

Mude para o diretório do repositório com cd ~/testing-with-duet-ai-codelab, se necessário, e insira o comando python3 main.py na janela do terminal:

3bf558e9cea15375.png

Clique no link http://127.0.0.1:8080 para abrir uma nova guia do navegador na página inicial do aplicativo:

fb06f382a4c03e4c.png

O aplicativo está sendo executado "localmente". Na verdade, o editor do Cloud Shell fez um pouco de mágica aqui. O aplicativo está sendo executado no Cloud Shell, não no seu computador. Quando você clicou no link, ele abriu uma guia não para o endereço local real http://127.0.0.1:8080, mas para um servidor proxy configurado apenas para essa finalidade pelo Cloud Shell. O efeito é o mesmo que se você estivesse executando o app localmente.

Faça um teste. Digite 25 e pressione Converter!

e1b9d5832f6d0058.png

Isso mesmo, 25 é XXV em algarismos romanos! Você precisa terminar esta etapa.

Talvez seja bom verificar mais alguns números. 25 funcionou, e 24?

37982e385e17baac.png

Talvez tenhamos sido um pouco apressados ao pensar que estava tudo bem. XXIIII é a conversão correta de 24? Não deveria ser XXIV?

Pode-se argumentar que XXIIII está correto, mas não é o que as pessoas geralmente esperam. Como não está realmente errado (observe que muitos relógios mostram 4 como o numeral romano IIII), deixe esse problema para uma melhoria futura.

Que tal tentar números negativos? Zero? Não há como representar esses números em algarismos romanos. Nada parece voltar para o usuário, o que parece um erro que precisa ser corrigido.

Os testes ajudam a encontrar e eliminar erros, e o Gemini Code Assist pode ajudar a escrever e usar testes.

5. Adicionar testes

Volte para a janela do Gemini Chat e pergunte

How can I test the number_to_roman function?

Leia a resposta, que deve incluir uma discussão sobre os módulos unittest e pytest.

Talvez você queira que o Gemini Code Assist escreva esses testes para você. Abra calendar.py, onde está o código de conversão real, no editor, volte para a janela do Gemini Chat e pergunte novamente

How can I test the number_to_roman function?

A resposta agora é mais específica, incluindo até mesmo um módulo de teste de unidade que você pode copiar ou injetar em um novo arquivo:

import unittest
import calendar

class NumberToRomanTest(unittest.TestCase):

    def test_convert_1(self):
        self.assertEqual(calendar.number_to_roman(1), "I")

    def test_convert_4(self):
        self.assertEqual(calendar.number_to_roman(4), "IV")

    def test_convert_9(self):
        self.assertEqual(calendar.number_to_roman(9), "IX")

    def test_convert_40(self):
        self.assertEqual(calendar.number_to_roman(40), "XL")

    def test_convert_90(self):
        self.assertEqual(calendar.number_to_roman(90), "XC")

    def test_convert_400(self):
        self.assertEqual(calendar.number_to_roman(400), "CD")

    def test_convert_900(self):
        self.assertEqual(calendar.number_to_roman(900), "CM")

    def test_convert_1990(self):
        self.assertEqual(calendar.number_to_roman(1990), "MCMXC")

    def test_convert_2023(self):
        self.assertEqual(calendar.number_to_roman(2023), "MMXXIII")

Talvez você veja um código diferente do exemplo acima. Os modelos subjacentes do Gemini Code Assist são atualizados periodicamente, então as respostas nem sempre serão as mesmas. Se você vir um conjunto de código diferente, poderá continuar com os exemplos mostrados neste codelab copiando o código aqui ou testar a resposta alternativa que o Gemini Code Assist está oferecendo. Se tiver tempo, você pode até tentar os dois caminhos. O Gemini Code Assist é um assistente de programação para você usar como quiser.

Clique na seta dupla no canto superior direito da janela do Gemini Chat para criar um arquivo com o código do teste de unidade ou use o ambiente de desenvolvimento integrado para criar um arquivo e colar o código mostrado neste laboratório. Pressione CTRL-S ou CMD-S nessa janela para salvar e nomeie o arquivo salvo como calendar-unittest.py.

Volte ao terminal e pressione CTRL-C para interromper o servidor da Web que você deixou em execução antes e receba um prompt do shell. Insira o comando

python3 calendar-unittest.py

para executar os novos testes.

Não há saída. Não era o que se esperava. Tudo passou em silêncio? Você gostaria de saber isso com certeza. Confira a resposta do Gemini Code Assist que incluiu o código de teste. Abaixo do código, havia mais informações sobre como executar o caso de teste:

run-unittest.png

Tente executar o comando recomendado:

python -m unittest discover

Pode haver um problema se a máquina não criar um alias do comando python3 para python. Nesse caso, execute:

python3 -m unittest discover

O comando é executado, mas retorna Ran 0 tests in 0.000s. O módulo tem vários testes. O que está acontecendo?

É a última palavra do comando, discover. De onde ela surgiu? Aparentemente, o Gemini Code Assist esperava que o código de teste fosse salvo em um arquivo chamado discover ou discover.py, mas não especificou que era isso que você deveria fazer. Como você salvou o arquivo em calendar-unittest.py, tente executar o comando:

python3 -m unittest calendar-unittest

Agora você vai ver muitas informações, começando com algo assim:

$ python3 -m unittest calendar-unittest
.F.FFFFFF
======================================================================
FAIL: test_convert_1990 (calendar-unittest.NumberToRomanTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/charles_engelke/testing-with-duet-ai-codelab/calendar-unittest.py", line 28, in test_convert_1990
    self.assertEqual(calendar.number_to_roman(1990), "MCMXC")
AssertionError: 'MDCCCCLXXXX' != 'MCMXC'
- MDCCCCLXXXX
+ MCMXC

A primeira linha mostra um período para cada teste aprovado e um F para cada teste reprovado. A maioria dos testes está falhando. Em seguida, ele lista os testes com falha individualmente, mostrando a saída esperada e a saída real. Não está claro em que ordem esses testes foram executados. Ela estava em ordem alfabética por nome do teste, não na ordem em que os testes aparecem no arquivo. Então, test_convert_1 foi executado primeiro, depois test_convert_1990, depois test_convert_2023 e assim por diante. Os casos de teste para 1 e 2023 foram os únicos aprovados.

Quando você testou esse código pela primeira vez, percebeu que ele converteu 24 em XXIIII, o que não estava exatamente errado, mas não era a forma comum em que IIII é convertido em IV. Todos os testes com falha eram para casos semelhantes. Quando esse problema foi observado pela primeira vez, o laboratório disse: "Como não está realmente errado (observe que muitos relógios mostram 4 como o numeral romano IIII), deixe esse problema para uma melhoria futura".

Você pode mudar os casos de teste para esperar e aceitar as respostas "não erradas" que o código recebe ou aceitar que é hora daquele "aprimoramento futuro". Então, a próxima etapa é corrigir o código com a ajuda do Gemini Code Assist para dar as respostas mais aceitáveis que os testes esperam.

6. Aprimorar o código

As respostas como XXIIII para 24, em vez do mais comum XXIV, foram consideradas "não realmente erradas" e adiadas para uma melhoria futura. Esse futuro é agora. Essas respostas "não tão erradas" ainda são irritantes.

A primeira regra para dígitos repetidos em números romanos é: sempre que você tiver quatro dígitos idênticos seguidos, eles devem ser substituídos por um dos dígitos seguido pelo próximo dígito maior. Portanto, XXIIII precisa ser substituído por XXIV. Da mesma forma, XXXX precisa ser mudado para XL, e CCCC precisa se tornar CD.

Pergunte ao Gemini Code Assist como mudar o valor da variável roman dessa forma pouco antes de ela ser retornada por number_to_roman:

If the final value of roman has IIII in it, that should be replaced by IV. Similarly XXXX should be replaced by XL, and CCCC should become CD. How can I make those changes?

A sugestão é adicionar um código no final:

6437c3fa2c5fabd1.png

Copie/cole ou digite essas linhas no editor e veja o que acontece:

dcefa568cab82fb7.png

O Gemini Code Assist adicionou mais linhas para lidar com os casos que podem surgir depois de fazer o primeiro conjunto de substituições. Por exemplo, 19 seria convertido em XVIIII, depois em XVIV e, finalmente, no correto XIX.

Se o Gemini Code Assist fez sugestões aparentemente úteis, pressione Tab para aceitar as recomendações, salve o arquivo e execute o servidor da Web novamente. Caso contrário, adicione as linhas mostradas no exemplo manualmente e salve o arquivo. Tente uma conversão difícil: 1999:

a206999587fdc9.png

Correto.

Execute os testes novamente. Todas elas passam!

O aplicativo da Web parece pronto para ser colocado em produção.

7. Implantar no Cloud Run

O Cloud Run executa um aplicativo conteinerizado na Internet para você. Para aplicativos escritos usando frameworks comuns, como o Flash, o comando gcloud run deploy até mesmo cria o contêiner antes de implantá-lo. Execute o comando:

gcloud run deploy

No terminal. Quando for solicitado o local do código-fonte, pressione "Enter" para aceitar o local correto sugerido. Da mesma forma, quando for solicitado um nome de serviço, pressione "Enter" para aceitar a sugestão.

O comando pode falhar porque a gcloud não consegue determinar qual projeto usar. Nesse caso, execute o comando:

gcloud config set core/project <project-id>

em que é substituído pelo ID do projeto, que pode ser o mesmo que o nome dele. Em seguida, execute o comando gcloud run deploy novamente.

  • O comando vai informar que algumas APIs são necessárias e ainda não estão ativadas. Digite y para ativar.
  • Quando for solicitado a selecionar uma região, escolha uma que seja conveniente para você. Inserir o número correspondente a us-central1 é uma opção segura.
  • Quando solicitado, digite Y para continuar.
  • Permita invocações não autenticadas desse serviço do Cloud Run. A opção de autenticação usada pelo Cloud Run é adequada para uso por programas que chamam o serviço. Como este é um site, você não vai usar a autenticação.

O Google Cloud vai criar e implantar o contêiner, rotear o tráfego para ele e definir políticas de acesso. Em seguida, ele vai mostrar o link para a página inicial:

94ba7d8d63a44afd.png

Acesse o link para abrir sua inscrição.

a2e51666dfd33a9f.png

Digite um número e pressione "Enter". Pronto!

5021535ac991a95c.png

O quê?!

Funcionou na sua máquina! Por que isso não está concluído?

Descubra. Pergunte ao Gemini Code Assist,

Why am I getting an internal server error on cloud run?

4b24321251d6eddf.png

Aparentemente, o Gemini Code Assist consegue ler o arquivo de registro, que diz algo semelhante. Vamos perguntar ao Gemini Code Assist como você pode consultar os registros:

92d1855be73ef1d.png

Vá em frente e crie as chaves. Procure linhas com indicadores de erro !! em vermelho, como abaixo:

9bed4f9ed82de21c.png

Isso é seguido por muitas linhas de detalhes sobre a pilha de chamadas chegando aqui, mas depois há isto:

47fc93be845f4e3f.png

Ao analisar o arquivo calendar.py, você vai encontrar a função number_to_roman. E você sabe que está certo porque funcionou na sua máquina. O que pode ser diferente no Cloud Run?

A resposta é complicada. Há um módulo padrão incluído no Python3 chamado calendar, assim como o arquivo calendar.py em que a função number_to_roman é definida. Na sua máquina local, quando o Python procurava um módulo chamado calendar, ele pesquisava primeiro no diretório do aplicativo. Aparentemente, o Python no Cloud Run procurou primeiro os módulos padrão, importou-os e não encontrou uma função number_to_roman.

Esses tipos de diferenças entre ambientes são sempre possíveis. Felizmente, quando um aplicativo é contêinerizado, ele carrega o ambiente em que está inserido. Assim, onde quer que você o execute, o comportamento será o mesmo. Se você tivesse executado o mesmo aplicativo em contêiner localmente que o Cloud Run, teria tido o mesmo problema.

Corrigir este problema. Mude o nome do módulo de agenda local para algo que não seja um nome de módulo padrão. Renomeie o arquivo calendar.py para my_calendar.py e mude as linhas import calendar em main.py e calendar-unittest.py para import my_calendar. Por fim, mude a linha

roman = calendar.number_to_roman(number)

a

roman = my_calendar.number_to_roman(number)

Teste localmente, execute os testes e faça uma nova implantação:

gcloud run deploy

Agora ele funciona:

ed288801c6825eb1.png

Você pode compartilhar esse URL, e todos que precisarem de uma ferramenta de conversão de números romanos poderão usar a sua.

8. Opcional: deixar mais bonito

Seu aplicativo está funcionando bem e acessível a qualquer pessoa na Web. Mas ele parece um pouco simples. Antes de contar para todo mundo, que tal pedir ao Gemini Code Assist para melhorar a aparência dele?

Abra o arquivo templates/index.html. Na conversa no Gemini, pergunte:

Make this index.html file use material design.

A resposta é adicionar ao arquivo atual, resultando em algo semelhante a isto:

<!DOCTYPE html>
<html>
<head>
    <title>Roman Numerals</title>
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">   
    <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>     
</head>
<body>
    <h1 class="mdl-typography--title">Roman Numerals</h1>
    <form action="/convert" method="post">
        <div class="mdl-textfield mdl-js-textfield">
            <input class="mdl-textfield__input" type="text" id="number" name="number" required />
            <label class="mdl-textfield__label" for="number">Enter a number:</label>
          </div>
          <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
            Convert!
          </button>
    </form>
</body>
</html>

Use o ícone para copiar o código sugerido e cole sobre o conteúdo atual de index.html. No terminal, execute python3 main.py e clique no link para abrir uma janela de visualização. A página está um pouco menos simples agora:

295643ec03fcaafc.png

Repita esse processo com o arquivo convert.html, se quiser.

O Gemini Code Assist conhece bastante CSS e pode ajudar você a estilizar as páginas do aplicativo de várias maneiras. Este é apenas o começo.

Como você quer compartilhar esse aplicativo, não se esqueça de reimplantá-lo no Cloud Run:

gcloud run deploy

Você pode passar o URL para as pessoas que precisam fazer a conversão.

9. Parabéns!

Parabéns! Você trabalhou com o Gemini Code Assist para adicionar testes a um aplicativo, corrigir erros nele e adicionar funcionalidades aprimoradas.

Quando terminar de usar o aplicativo criado, exclua-o do painel do console do Cloud para evitar possíveis cobranças futuras.

Documentos de referência…