Introducción a las pruebas con Gemini Code Assist

1. Introducción

En este lab, usarás Gemini Code Assist, un colaborador potenciado por IA en Google Cloud, para agregar pruebas a una aplicación web de Python existente y encontrar y corregir errores en esa aplicación expuesta por las pruebas. Luego, usarás Code Assist para crear pruebas de funcionalidades nuevas y generar código que permita pasar esas pruebas y extender la app.

Actividades

  • Usarás el editor de Cloud Shell para descargar el código de una aplicación web existente.
  • Usarás Gemini Code Assist Chat en el editor de Cloud Shell para hacer preguntas generales sobre Google Cloud.
  • Usarás la asistencia para código intercalada de Gemini Code Assist en el editor de Cloud Shell para generar pruebas para la aplicación, ejecutarlas, encontrar y corregir errores y, luego, extender la funcionalidad de la aplicación.

Qué aprenderás

  • Cómo usar Gemini Code Assist para varias tareas de desarrolladores, como la generación de pruebas y de código
  • Cómo usar Gemini Code Assist para obtener información sobre Google Cloud

Qué necesitarás

  • Navegador web Chrome
  • Una cuenta de Gmail
  • Un proyecto de Cloud con la facturación habilitada
  • Gemini Code Assist habilitado para tu proyecto de Cloud

Este lab está dirigido a desarrolladores de todos los niveles, incluidos principiantes. Aunque la aplicación de ejemplo está en lenguaje Python, no necesitas conocer la programación de Python para entender lo que está sucediendo. Nos enfocaremos en familiarizarte con las capacidades de Gemini Code Assist para desarrolladores.

2. Configuración

Ya deberías tener un proyecto de Cloud con la facturación habilitada para usar en este lab. Ahora habilitaremos la API de Gemini en nuestro proyecto de Google Cloud. Sigue los pasos que se indican a continuación:

  1. Ve a https://console.cloud.google.com y asegúrate de haber seleccionado el proyecto de Google Cloud con el que planeas trabajar en este lab. Haz clic en el ícono de Gemini que ves en la parte superior derecha.

GeminiBanner.png

  1. La ventana de la consola de Gemini para Cloud se abrirá en el lado derecho de la consola. Haz clic en el botón Habilitar si aparece a continuación. Si no ves el botón Habilitar y, en su lugar, ves una interfaz de Chat, significa que ya habilitaste Gemini para Cloud para el proyecto y puedes ir directamente al siguiente paso.

GeminiApiEnable.png

  1. Una vez que esté habilitado, podrás probar Gemini haciendo una o dos consultas. Se muestran algunas consultas de ejemplo, pero puedes intentar algo como ¿Qué es Cloud Run?

GeminiChatWindow.png

Code Assist te responderá con la respuesta a tu pregunta. Puedes hacer clic en el ícono f68286b2b2ea5c0a.png en la esquina superior derecha para cerrar la ventana de chat de Code Assist.

Habilita Gemini en el Editor de Cloud Shell

Gemini Code Assist está disponible y se comporta de manera similar en varios IDE populares. En este codelab, usarás el editor de Google Cloud Shell, que se ejecuta completamente en tu navegador web. Debes habilitar y configurar Gemini en el Editor de Cloud Shell. Sigue estos pasos:

  1. Inicia Cloud Shell con el ícono que se muestra a continuación. El inicio de la instancia de Cloud Shell puede tardar uno o dos minutos.

72dc3df7b007fcde.png

  1. Haz clic en el botón Editor o Abrir editor (según sea el caso) y espera hasta que aparezca el editor de Cloud Shell. Si ves el botón Probar el nuevo editor, haz clic en él.

CloudShellEditor.png

  1. Haz clic en el botón Cloud Code - Acceder en la barra de estado de la parte inferior como se muestra. Autoriza el complemento según las instrucciones. Si ves "Cloud Code (ningún proyecto)" en la barra de estado, selecciónalo y elige el proyecto específico de Google Cloud de la lista de proyectos con los que planeas trabajar.

CloudCodeSignIn.png

  1. Si no ves el ícono de Gemini en la barra de estado de la parte inferior derecha, deberás habilitarlo en Cloud Code. Antes de hacerlo, asegúrate de que Gemini (antes conocido como Duet AI para desarrolladores) esté habilitado en el IDE. Para ello, ve a Cloud Code Extension → Configuración y, luego, ingresa el texto Duet AI: Enable como se muestra a continuación. Asegúrate de que la casilla de verificación esté seleccionada. Debes volver a cargar el IDE. Esto habilita Gemini en Cloud Code, y la barra de estado de Gemini aparecerá en tu IDE.

EnableDuetAiSetting.png

  1. Haz clic en el botón Gemini en la esquina inferior derecha como se muestra y selecciona el proyecto de Google Cloud correcto para el que habíamos habilitado la API de Cloud AI Companion.

GeminiSelectGoogleCloudProject.png

  1. Una vez que selecciones tu proyecto de Google Cloud, asegúrate de poder verlo en el mensaje de estado de Cloud Code en la barra de estado y de que también tienes Gemini habilitado a la derecha, en la barra de estado, como se muestra a continuación:

GeminiEnabledStatusBar.png

Gemini Code Assist está listo para que lo uses

3. Descarga y examina la aplicación

En la ventana de la terminal, ejecuta el comando para clonar el repositorio con el código de inicio y, luego, cambia al directorio nuevo (si la ventana de la terminal ya no está abierta, haz clic en el botón Terminal o Abrir terminal para restablecerla):

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

Abre main.py en el editor y, luego, haz clic en el ícono del chat de Gemini ubicado en el lado izquierdo del editor para abrir la ventana de Gemini Chat. Esta ventana de Gemini Chat está dentro del IDE y tiene el código de este disponible como contexto de debate. Escribe la instrucción Explica esto y visualiza la respuesta:

GeminiChatExplainThis.png

Puedes desplazarte por esta ventana de chat para ver la respuesta completa. En la explicación, se indica que podemos ejecutar este programa de forma local con el comando python3 main.py en la ventana de terminal.

4. Ejecuta de forma local

Si es necesario, cambia al directorio del repositorio con cd ~/testing-with-duet-ai-codelab y, luego, ingresa el comando python3 main.py en la ventana de la terminal:

3bf558e9cea15375.png

Haz clic en el vínculo http://127.0.0.1:8080 para abrir una nueva pestaña del navegador en la página principal de la aplicación:

fb06f382a4c03e4c.png

La aplicación se ejecuta “de forma local”. En realidad, el editor de Cloud Shell hizo un poco de magia aquí. La aplicación se ejecuta en Cloud Shell, no en tu propia computadora. Cuando hiciste clic en el vínculo, se abrió una pestaña no para la dirección local real http://127.0.0.1:8080, sino para un servidor proxy configurado solo para este propósito por Cloud Shell. El efecto es el mismo que si lo estuvieras ejecutando de forma local.

Pruébalo. Ingresa 25 y presiona Convert!.

e1b9d5832f6d0058.png

Así es, 25 es XXV en números romanos. Debes terminar aquí.

Tal vez debas revisar algunos números más. 25 funcionaron, ¿y 24?

37982e385e17baac.png

Quizás estábamos un poco apresurados de pensar que todo estaba bien. ¿XXIIII es la conversión correcta para 24? ¿No debería ser XXIV?

Se podría argumentar que XXIIII es correcto, pero no es realmente lo que las personas esperan. Sin embargo, dado que no es realmente incorrecto (ten en cuenta que muchos relojes muestran 4 como número romano IIII), deja ese problema para una mejora futura.

¿Y si pruebas con números negativos? ¿Cero? No hay forma de representar esos números en números romanos. El usuario no ve nada, lo que parece un error que se debe solucionar.

Las pruebas pueden ayudar a encontrar y eliminar errores, y Gemini Code Assist nos ayuda a escribir y usar pruebas.

5. Agrega pruebas

Regresa a la ventana de Gemini Chat y pregúntale

How can I test the number_to_roman function?

Lee la respuesta, que debe incluir la discusión sobre los módulos unittest y pytest.

Es posible que quieras que Gemini Code Assist escriba estas pruebas por ti. Abre calendar.py, donde se encuentra el código de conversión real, en el editor, regresa a la ventana de Gemini Chat y vuelve a preguntar.

How can I test the number_to_roman function?

Ahora, la respuesta es más específica, incluso incluye un módulo de prueba de unidades que puedes copiar o insertar en un archivo nuevo:

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")

Es posible que veas un código diferente al del ejemplo anterior. Los modelos subyacentes de Gemini Code Assist se actualizan periódicamente, por lo que las respuestas no siempre son iguales. Si ves un conjunto de código diferente, ahora puedes elegir si quieres continuar con las muestras de este codelab copiando el código que aparece aquí, o bien puedes probar la respuesta alternativa que Gemini Code Assist te ofrece. Si tienes tiempo, incluso puedes probar ambos caminos. Gemini Code Assist es un asistente de programación que puedes usar como mejor te parezca.

Haz clic en la flecha de doble punta de la esquina superior derecha de la ventana de Gemini Chat para crear un archivo nuevo que contenga el código de prueba de unidades, o bien usa el IDE para crear un archivo nuevo y pega el código que se muestra en este lab. Presione CTRL-S o CMD-S en esa ventana para guardarla y llame al archivo calendar-unittest.py guardado.

Regresa a la terminal y presiona CTRL-C para detener el servidor web que dejaste en ejecución anteriormente y obtener un símbolo del sistema en la shell. Ingresa el comando

python3 calendar-unittest.py

para ejecutar las pruebas nuevas.

No hay resultados. No es lo que esperaba. ¿Todo salió en silencio? Te gustaría saberlo con certeza. Mira la respuesta de Gemini Code Assist que incluía el código de prueba. Debajo del código, había más información sobre cómo ejecutar el caso de prueba:

run-unittest.png

Intenta ejecutar el comando recomendado:

python -m unittest discover

Es posible que tengas un problema si tu máquina no asigna un alias al comando python3 a python, en cuyo caso se ejecuta:

python3 -m unittest discover

El comando se ejecuta, pero muestra Ran 0 tests in 0.000s. El módulo tiene varias pruebas. ¿Qué sucede?

Es la última palabra del comando, discover. ¿De dónde provino? Al parecer, Gemini Code Assist esperaba que el código de la prueba se guardara en un archivo llamado discover o discover.py, pero no especificó que eso era lo que debías hacer. Como realmente guardaste el archivo en calendar-unittest.py, intenta ejecutar el comando:

python3 -m unittest calendar-unittest

Ahora verás muchos resultados. Comenzarás con algo como el siguiente:

$ 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

En la primera línea, se muestra un punto por cada prueba aprobada y un F por cada prueba fallida. La mayoría de las pruebas fallan. Luego, enumera las pruebas fallidas de forma individual y muestra el resultado esperado y el resultado real. No está claro en qué orden se ejecutaron estas pruebas. Estaba en orden alfabético por nombre de prueba, no por el orden en el que aparecen las pruebas en el archivo. Por lo tanto, primero se ejecutó test_convert_1, luego test_convert_1990, después test_convert_2023, y así sucesivamente. Los casos de prueba de 1 y 2023 son los únicos que se aprobaron.

Cuando probaste este código por primera vez, notaste que convertiste 24 en XXIIII, que no era exactamente incorrecta, pero no era la forma común en la que IIII se convierte en IV. Todas las pruebas fallidas fueron en casos similares. Cuando se observó este problema por primera vez, el lab dijo lo siguiente: "Sin embargo, como no es realmente incorrecto (ten en cuenta que muchos relojes muestran 4 como número romano IIII), deja ese problema para una mejora futura.

Puedes modificar los casos de prueba para esperar y aceptar el mensaje “no incorrecto”. responde el código que se te proporcionó o acepta que es momento de esa "mejora futura". Por lo tanto, el siguiente paso es corregir el código, con la ayuda de Gemini Code Assist, para brindar las respuestas más aceptables que esperan las pruebas.

6. Cómo mejorar el código

Recuerda que las respuestas como XXIIII para 24, en lugar de las XXIV más comunes, se consideraron "no son realmente incorrectas". y se pospusieron para una mejora futura. El futuro es hoy Aquellas que "no están realmente incorrectas" respuestas aún son molestas.

La primera regla para los dígitos repetidos en números romanos es: cada vez que tengas cuatro dígitos idénticos consecutivos, se deben reemplazar por uno de los dígitos seguido del siguiente dígito más alto. Por lo tanto, XXIIII debe reemplazarse por XXIV. De manera similar, XXXX debe cambiarse a XL, y CCCC debe convertirse en CD.

Pregúntale a Gemini Code Assist cómo cambiar el valor de la variable roman de esta manera justo antes de que lo muestre 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?

La sugerencia es agregar algo de código al final:

6437c3fa2c5fabd1.png

Copia, pega o escribe esas líneas en el editor y, luego, observa lo que sucede:

dcefa568cab82fb7.png

Gemini Code Assist agregó más líneas para manejar los casos en los que puedes terminar después de realizar el primer conjunto de sustituciones. Por ejemplo, 19 se convertiría al XVIIII, luego al XVIV y, por último, al XIX correcto.

Si Gemini Code Assist realizó sugerencias aparentemente útiles, presiona Tab para aceptarlas, guardar el archivo y volver a ejecutar el servidor web. De lo contrario, agrega manualmente las líneas que se muestran en este ejemplo y guarda el archivo. Prueba con una conversión difícil: 1999:

a206999587fdc9.png

Correcto.

Vuelve a ejecutar las pruebas ahora. ¡Todos pasan!

La aplicación web parece lista para ponerse en producción.

7. Implementa en Cloud Run

Cloud Run ejecutará por ti una aplicación alojada en contenedores en Internet. Para las aplicaciones escritas con frameworks comunes, como Flash, el comando gcloud run deploy incluso creará el contenedor por ti antes de implementarlo. Ejecuta el siguiente comando:

gcloud run deploy

En la terminal. Cuando se te pregunte la ubicación del código fuente, presiona Intro para aceptar la ubicación correcta que sugiere. De manera similar, cuando se te solicite el nombre de un servicio, presiona Intro para aceptar la sugerencia.

El comando puede fallar porque gcloud no puede determinar qué proyecto usar. En ese caso, ejecuta el siguiente comando:

gcloud config set core/project <project-id>

En el ejemplo anterior, se reemplaza por el ID de tu proyecto, que puede ser igual que su nombre. Luego, vuelve a ejecutar el comando gcloud run deploy.

  • El comando te indicará que se necesitan ciertas APIs y aún no están habilitadas. Ingresa “Y” para habilitarlas.
  • Cuando se te solicite seleccionar una región, elige la que te resulte más conveniente. Es una opción segura ingresar el número correspondiente a us-central1.
  • Cuando se te solicite, ingresa Y para continuar.
  • Es posible que permitas las invocaciones no autenticadas de este servicio de Cloud Run. La opción de autenticación que usa Cloud Run es adecuada para que la usen los programas que llaman al servicio. Como se trata de un sitio web, no usarás autenticación.

Google Cloud compilará el contenedor, lo implementará, enrutará el tráfico hacia él, establecerá las políticas de acceso y, luego, te mostrará el vínculo a la página principal:

94ba7d8d63a44afd.png

Puedes ir a ese vínculo y acceder a tu aplicación.

a2e51666dfd33a9f.png

Escribe un número, presiona Enter y listo.

5021535ac991a95c.png

¿Qué?

¡Funcionó en tu máquina! ¿Por qué no terminó esto?

Descúbrelo. Pregúntale a Gemini Code Assist,

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

4b24321251d6eddf.png

Parece que Gemini Code Assist puede leer el archivo de registro, lo que dice algo similar. Preguntemos a Gemini Code Assist cómo puedes revisar los registros por tu cuenta:

92d1855be73ef1d.png

Adelante, hazlo. Busca líneas con el signo !! de color rojo. indicadores de error, como se muestra a continuación:

9bed4f9ed82de21c.png

A esto le siguen muchas líneas de detalle sobre la pila de llamadas que llegan aquí, pero después se muestra lo siguiente:

47fc93be845f4e3f.png

Cuando miras tu archivo calendar.py, ves la función number_to_roman allí mismo. Y sabes que es correcto porque funcionó en tu máquina. ¿Qué podría ser diferente en Cloud Run?

La respuesta es complicada. Hay un módulo estándar incluido en Python3 llamado calendar, al igual que el archivo calendar.py en el que se define la función number_to_roman. En tu máquina local, cuando Python buscó un módulo llamado calendario, primero buscó el directorio de tu aplicación. Aparentemente, Python en Cloud Run buscó primero módulos estándar, los importó y no encontró una función number_to_roman.

Este tipo de diferencias en los entornos siempre son posibles. Afortunadamente, cuando una aplicación está alojada en contenedores, lleva su entorno dentro de ella, por lo que, dondequiera que la ejecute, se puede esperar el mismo comportamiento. Si hubieras ejecutado localmente la misma aplicación alojada en contenedores que Cloud Run, habrías tenido el mismo problema.

Solucionar este problema. Debes cambiar el nombre de tu módulo de calendario local por uno que no sea también un nombre de módulo estándar. Cambia el nombre del archivo calendar.py por my_calendar.py y, luego, cambia las líneas de import calendar en main.py y calendar-unittest.py por import my_calendar. Por último, cambia la línea

roman = calendar.number_to_roman(number)

para

roman = my_calendar.number_to_roman(number)

Pruébalo de manera local, ejecuta las pruebas y, luego, vuelve a implementarla:

gcloud run deploy

Y ahora funciona:

ed288801c6825eb1.png

Puedes compartir esta URL, y todos los que necesiten una herramienta de conversión de números romanos podrán usar la tuya.

8. Opcional: Mejora el aspecto

Tu aplicación se ejecuta correctamente y cualquier usuario de la Web puede acceder a ella. Pero se ve un poco simple. Antes de contarles a todos sobre ella, ¿por qué no pedirle a Gemini Code Assist que mejore su apariencia?

Abre el archivo templates/index.html. En la ventana del chat de Gemini, pregunta lo siguiente:

Make this index.html file use material design.

La respuesta es hacer adiciones en el archivo actual, lo que da como resultado algo similar a lo siguiente:

<!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>

Usa el ícono para copiar el código sugerido y pega el contenido existente del archivo index.html. En la terminal, ejecuta python3 main.py y haz clic en el vínculo para abrir una ventana de vista previa. Ahora, la página es un poco menos simple:

295643ec03fcaafc.png

Si lo deseas, puedes repetir esto con el archivo convert.html.

Gemini Code Assist conoce bastante CSS, y puedes hacer que te ayude a diseñar las páginas de la aplicación de diferentes maneras. Esto es solo el comienzo.

Dado que quieres compartir esta aplicación, no olvides volver a implementarla en Cloud Run:

gcloud run deploy

Puedes pasar la URL a las personas que deban convertir a números romanos.

9. ¡Felicitaciones!

¡Felicitaciones! Trabajaste correctamente con Gemini Code Assist para agregar pruebas a una aplicación, corregir errores en ella y agregar funciones mejoradas.

Cuando termines de usar la aplicación que compilaste, puedes borrarla del panel de la consola de Cloud para evitar posibles cargos futuros.

Documentos de referencia