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 em Python, além de encontrar e corrigir erros nesse aplicativo exposto 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 ampliar o app.

O que você vai fazer…

  • Você usará o Editor do Cloud Shell para fazer o download do código de um aplicativo da Web atual.
  • Você vai usar o Gemini Code Assist Chat no Cloud Shell Editor 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 testes para o aplicativo, executá-los, encontrar e corrigir erros e depois ampliar 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 saber mais sobre o Google Cloud.

O que é necessário…

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

Este laboratório é voltado para desenvolvedores com todos os níveis de conhecimento, inclusive iniciantes. Embora o aplicativo de exemplo esteja na linguagem Python, você não precisa estar familiarizado com a programação em Python para entender o que está acontecendo. Nosso foco será conhecer os recursos do Gemini Code Assist para desenvolvedores.

2. Configuração

Você já deve ter um projeto do Cloud com o faturamento ativado para usar neste laboratório. Agora vamos ativar 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 console do Gemini para Cloud é aberta no lado direito do console. Clique no botão Ativar, se mostrado abaixo. Se o botão Ativar não aparecer e, em vez disso, uma interface do Chat for exibida, você já ativou o Gemini para o Cloud no projeto e pode avançar diretamente para a próxima etapa.

GeminiApiEnable.png

  1. Depois de ativado, você pode testar o Gemini fazendo uma ou duas consultas. Alguns exemplos de consultas são mostrados, mas você pode tentar algo como O que é o Cloud Run?

GeminiChatWindow.png

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

Ative o Gemini no editor do Cloud Shell

O Gemini Code Assist está disponível e se comporta de maneira semelhante em vários ambientes de desenvolvimento integrado conhecidos. Neste codelab, você vai usar o Editor do Google Cloud Shell, que é executado totalmente no navegador da Web. Você precisa ativar e configurar o Gemini no editor do Cloud Shell. 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 seja exibido. 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, você precisará ativá-lo no Cloud Code. Antes de fazer isso, verifique se o Gemini (anteriormente conhecido como Duet AI para desenvolvedores) está ativado no ambiente de desenvolvimento integrado. 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. Atualize o ambiente de desenvolvimento integrado. Isso ativa o Gemini no Cloud Code, e a barra de status do Gemini aparecerá 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 ativamos a API Cloud AI Companion.

GeminiSelectGoogleCloudProject.png

  1. Depois de selecionar o projeto do Google Cloud, verifique se você consegue ver a mensagem de status do Cloud Code na barra de status e se o Gemini também está ativado à direita, na barra de status, conforme mostrado abaixo:

GeminiEnabledStatusBar.png

O Gemini Code Assist está pronto para uso.

3. Fazer o download e examinar o aplicativo

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

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

Abra o arquivo main.py no editor e clique no ícone de chat do Gemini no lado esquerdo do editor para abrir a janela do Gemini Chat. A janela do Gemini Chat está dentro do ambiente de desenvolvimento integrado e tem o código nele disponível como contexto para discussão. Digite a instrução Explique isto e veja a resposta:

GeminiChatExplainThis.png

Role a janela deste chat para conferir a resposta completa. A explicação diz que é possível 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 para a 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, e não no seu computador. Quando você clicou no link, ele abriu uma guia não para o endereço local http://127.0.0.1:8080, mas para um servidor proxy configurado para essa finalidade pelo Cloud Shell. O efeito é o mesmo que se ele estivesse sendo executado localmente.

Confira! Digite 25 e pressione Converter!

e1b9d5832f6d0058.png

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

Verifique mais alguns números. 25 funcionaram, e 24?

37982e385e17baac.png

Talvez estivéssemos um pouco apressados para pensar que estava tudo bem. XXIIII é a conversão correta para 24? Não deveria ser XXIV?

Pode-se argumentar que XXIIII está certo, mas não é o que as pessoas normalmente esperam. No entanto, como isso não está errado (observe que muitos relógios mostram 4 como numeral romano IIII), esse problema pode ser aplicado a um aprimoramento futuro.

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

Os testes podem ajudar a encontrar e eliminar erros, e o Gemini Code Assist pode nos ajudar a criar e usar testes.

5. Adicionar testes

Retorne à janela do Gemini Chat e pergunte

How can I test the number_to_roman function?

Leia a resposta, que deve incluir a discussão do módulo unittest e pytest.

É recomendável que o Gemini Code Assist crie esses testes para você. Abra o arquivo 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 unittest 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. Caso você veja um conjunto de códigos diferente, agora pode escolher se quer continuar com os exemplos mostrados neste codelab copiando o código mostrado aqui ou pode testar a resposta alternativa que o Gemini Code Assist agora oferece. Se tiver tempo, tente os dois caminhos. O Gemini Code Assist é um assistente de programação que você pode usar como quiser.

Clique na seta de ponta 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 cole o código mostrado neste laboratório. Pressione CTRL-S ou CMD-S nessa janela para salvá-lo e chame o arquivo calendar-unittest.py salvo.

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. Digite o comando

python3 calendar-unittest.py

para executar os novos testes.

Não há saída. Não era isso que eu esperava. Tudo passou silenciosamente? Você gostaria de saber disso, com certeza. Veja 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

Poderá haver um problema se sua máquina não atribuir alias ao comando python3 a 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 no comando, discover. De onde veio? 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 isso. Como você salvou o arquivo em calendar-unittest.py, tente executar o comando:

python3 -m unittest calendar-unittest

Agora você verá uma grande saída, 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 um com falha. A maioria dos testes está falhando. Ele lista individualmente os testes com falha, mostrando a saída esperada e real. Não está claro a ordem em que esses testes foram executados. Ele estava em ordem alfabética por nome de teste, e não na ordem em que os testes aparecem no arquivo. Portanto, 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 são os únicos que foram 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 no formato comum em que IIII é convertido em IV. Todos os testes reprovados foram para casos semelhantes. Quando esse problema foi observado pela primeira vez, o laboratório disse: "Como isso não está errado (observe que muitos relógios mostram 4 como numeral romano IIII), deixe esse problema para melhorias futuras."

Você pode mudar os casos de teste para esperar e aceitar as respostas "não erradas" fornecidas pelo código ou aceitar que é hora desse "aprimoramento futuro". Portanto, sua 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. Como melhorar o código

Lembre-se de que respostas como XXIIII para 24, em vez das XXIV mais comuns, foram consideradas "não realmente erradas" e foram adiadas para melhorias futuras. Esse futuro é agora. Essas respostas "não realmente erradas" ainda são irritantes.

A primeira regra para dígitos repetidos em numerais romanos é: sempre que houver quatro dígitos idênticos em uma linha, eles devem ser substituídos por um dos dígitos seguidos pelo próximo dígito mais alto. Portanto, XXIIII precisa ser substituído por XXIV. Da mesma forma, XXXX precisa ser mudado para XL, e CCCC precisa se tornar CD.

Peça ao Gemini Code Assist como alterar o valor da variável roman dessa maneira logo 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?

Sugerimos adicionar 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 em que você pode acabar depois de fazer o primeiro conjunto de substituições. Por exemplo, 19 seria convertido em XVIIII, depois em XVIV e, finalmente, no XIX correto.

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 manualmente as linhas mostradas no exemplo e salve o arquivo. Tente uma conversão difícil: 1999:

a206999587fdc9.png

Correto.

Execute os testes novamente. Todos eles passaram!

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

7. Implantam no Cloud Run

O Cloud Run vai executar um aplicativo conteinerizado na Internet para você. No caso de aplicativos criados com frameworks comuns, como o Flash, o comando gcloud run deploy cria esse contêiner para você antes de implantá-lo. Execute o comando:

gcloud run deploy

No terminal. Quando o local do código-fonte for perguntado, pressione Enter para aceitar o local correto sugerido. Da mesma forma, quando um nome de serviço for solicitado, 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 igual ao nome dele. Em seguida, execute novamente o comando gcloud run deploy.

  • O comando vai perguntar se determinadas APIs são necessárias, mas ainda não foram ativadas. Digite "y" para ativá-las.
  • Quando for solicitado que você selecione uma região, escolha uma conveniente para você. Inserir o número correspondente a us-central1 é uma opção segura.
  • Quando solicitado, digite Y para continuar.
  • Permita invocações unauthenticated desse serviço do Cloud Run. A opção de autenticação usada pelo Cloud Run é adequada para programas que chamam o serviço. Como este é um site, a autenticação não será usada.

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

94ba7d8d63a44afd.png

Acesse esse link e acesse o aplicativo.

a2e51666dfd33a9f.png

Digite um número, pressione Enter e Tada!

5021535ac991a95c.png

O quê?!

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

Descubra. Fale com o Gemini Code Assist,

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

4b24321251d6eddf.png

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

92d1855be73ef1d.png

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

9bed4f9ed82de21c.png

Isso é seguido por muitas linhas de detalhes na pilha de chamadas que chega até aqui, mas há isto:

47fc93be845f4e3f.png

Ao observar o arquivo calendar.py, você verá a função number_to_roman. E 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 no qual a função number_to_roman está definida. Na máquina local, quando o Python procurou um módulo chamado calendar, ele pesquisou no seu diretório de aplicativos primeiro. Aparentemente, o Python no Cloud Run procurou primeiro módulos padrão, importou-os e não encontrou uma função number_to_roman.

Esse tipo de diferença nos ambientes é sempre possível. Felizmente, quando um aplicativo é conteinerizado, ele carrega o ambiente dentro dele. Portanto, onde quer que ele seja executado, o mesmo comportamento será esperado. Se você tivesse executado localmente o mesmo aplicativo conteinerizado que o Cloud Run, você teria tido o mesmo problema.

Corrigir esse problema. Você precisa alterar o nome do módulo da agenda local para um nome que não seja um módulo padrão. Renomeie o arquivo calendar.py como my_calendar.py e, em seguida, altere as linhas import calendar em main.py e calendar-unittest.py para import my_calendar. Por fim, altere a linha

roman = calendar.number_to_roman(number)

a

roman = my_calendar.number_to_roman(number)

Faça o teste localmente, execute os testes e reimplante:

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 o seu.

8. Opcional: melhorar a aparência

O aplicativo está funcionando normalmente e pode ser acessado por qualquer pessoa na Web. Mas é um pouco simples. Antes de contar a todos sobre isso, por que não pedir ao Gemini Code Assist para melhorar a aparência dele?

Abra o arquivo templates/index.html. Na janela do chat do Gemini, pergunte:

Make this index.html file use material design.

A resposta é fazer adições ao arquivo atual, resultando em algo semelhante ao seguinte:

<!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 colar sobre o conteúdo existente 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

Você pode repetir isso com o arquivo convert.html, se quiser.

O Gemini Code Assist conhece bem o CSS, e ele pode ajudar a estilizar as páginas do aplicativo de várias maneiras. Isso é apenas o começo.

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

gcloud run deploy

Você pode transmitir o URL para as pessoas que precisam fazer a conversão para numerais romanos.

9. Parabéns!

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

Quando terminar de usar o aplicativo criado, você poderá excluí-lo do painel do console do Cloud para evitar cobranças futuras.

Documentos de referência…