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 los errores que las pruebas expongan en esa aplicación. Luego, usarás Code Assist para crear pruebas para la nueva funcionalidad y generar código para aprobar esas pruebas y extender la app.
Actividades
- Usarás el editor de Cloud Shell para descargar código de una aplicación web existente.
- Usarás el chat de Gemini Code Assist en el editor de Cloud Shell para hacer preguntas generales sobre Google Cloud.
- Usarás la asistencia de código insertado 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 completar distintas tareas de desarrollador, como la generación de pruebas y la generación de código
- Cómo usar Gemini Code Assist para aprender 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 muestra está en lenguaje Python, no es necesario que sepas programar en ese lenguaje para entender lo que se hace. Nuestro enfoque será que te familiarices con las funciones 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:
- 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 esquina superior derecha.

- 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 se muestra a continuación. Si no ves el botón Habilitar y, en cambio, ves una interfaz de chat, ya habilitaste Gemini para Cloud en el proyecto y puedes continuar directamente con el siguiente paso.

- Una vez que esté habilitada, haz una o dos consultas para probar Gemini. Se muestran algunas consultas de ejemplo, pero puedes probar con algo como ¿Qué es Cloud Run?

Code Assist responderá tu pregunta. Puedes hacer clic en el ícono
de 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. Los pasos se indican a continuación:
- 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.

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

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

- 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 Extensión de Cloud Code → Configuración y, luego, ingresa el texto Duet AI: Habilitar como se muestra a continuación. Asegúrate de que la casilla de verificación esté seleccionada. Debes volver a cargar tu IDE. De esta manera, se habilitará Gemini en Cloud Code, y la barra de estado de Gemini aparecerá en tu IDE.

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

- Una vez que selecciones tu proyecto de Google Cloud, asegúrate de que puedas verlo en el mensaje de estado de Cloud Code en la barra de estado y de tener Gemini habilitado en la barra de estado del lado derecho, como se muestra a continuación:

¡Gemini Code Assist está listo para usarse!
3. Descarga y examina la aplicación
En la ventana de terminal, ejecuta el comando para clonar el repositorio con el código inicial y, luego, cambia al directorio nuevo (si la ventana de 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 de chat de Gemini que se encuentra a la izquierda del editor para abrir la ventana de Gemini Chat. Esta ventana de Gemini Chat se encuentra dentro del IDE y tiene el código del IDE disponible como contexto para la conversación. Ingresa la instrucción Explica esto y mira la respuesta:

Puedes desplazarte por esta ventana de chat para ver la respuesta completa. La explicación dice que podemos ejecutar este programa de forma local con el comando python3 main.py en la ventana de la 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:

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:

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 computadora. Cuando hiciste clic en el vínculo, se abrió una pestaña no en la dirección local real http://127.0.0.1:8080, sino en un servidor proxy configurado solo para este propósito por Cloud Shell. El efecto es el mismo que si realmente lo ejecutaras de forma local.
Pruébalo. Ingresa 25 y presiona Convertir.

Así es, 25 es XXV en números romanos. Ya debes haber terminado.
Quizás deberías verificar algunos números más. 25 funcionó, ¿y 24?

Quizás nos apresuramos un poco a 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 lo que la gente suele esperar. Sin embargo, como no es realmente incorrecto (ten en cuenta que muchos relojes muestran el 4 como el número romano IIII), deja ese problema para una mejora futura.
¿Qué tal si probamos con números negativos? ¿Cero? No hay forma de representar esos números en números romanos. Parece que no se devuelve nada al usuario, lo que parece un error que debe abordarse.
Las pruebas pueden ayudar a encontrar y eliminar errores, y Gemini Code Assist puede ayudarnos a escribir y usar pruebas.
5. Cómo agregar pruebas
Regresa a la ventana de Gemini Chat y pregunta lo siguiente:
How can I test the number_to_roman function?
Lee la respuesta, que debería incluir una explicació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, vuelve 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 y hasta incluye un módulo de prueba unitaria 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 del ejemplo anterior. Los modelos subyacentes de Gemini Code Assist se actualizan periódicamente, por lo que las respuestas no siempre serán las mismas. Si ves un conjunto de código diferente, puedes copiar el código que se muestra aquí para continuar con las muestras de este codelab o probar la respuesta alternativa que te ofrece Gemini Code Assist. Si tienes tiempo, puedes incluso 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 que se encuentra en la esquina superior derecha de la ventana de Gemini Chat para crear un archivo nuevo que contenga el código de la prueba de unidades, o bien usa el IDE para crear un archivo nuevo y pegar el código que se muestra en este lab. Presiona CTRL + S o CMD + S en esa ventana para guardarlo y llama al archivo guardado calendar-unittest.py.
Vuelve a la terminal y presiona Ctrl + C para detener el servidor web que dejaste en ejecución antes y obtener un símbolo del sistema. Ingresa el comando
python3 calendar-unittest.py
para ejecutar las pruebas nuevas.
No hay ningún resultado. No es lo que se esperaba. ¿Todo pasó de forma silenciosa? Te gustaría saberlo con certeza. Vuelve a consultar 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:

Intenta ejecutar el comando recomendado:
python -m unittest discover
Es posible que tengas un problema si tu máquina no crea un alias del comando python3 para python, en cuyo caso, ejecuta lo siguiente:
python3 -m unittest discover
El comando se ejecuta, pero devuelve 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? Aparentemente, Gemini Code Assist esperaba que el código de prueba se guardara en un archivo llamado discover o discover.py, pero no especificó que eso era lo que debías hacer. Como guardaste el archivo en calendar-unittest.py, intenta ejecutar el siguiente comando:
python3 -m unittest calendar-unittest
Ahora verás muchos resultados, comenzando con algo como lo 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
La primera línea muestra un período para cada prueba aprobada y un F para cada una de las que fallaron. La mayoría de las pruebas fallan. Luego, se enumeran las pruebas fallidas de forma individual, y se muestran el resultado esperado y el resultado real. No queda claro en qué orden se ejecutaron estas pruebas. Estaba en orden alfabético por nombre de la prueba, no en el orden en que aparecen las pruebas en el archivo. Por lo tanto, test_convert_1 se ejecutó primero, luego test_convert_1990, luego test_convert_2023, y así sucesivamente. Los casos de prueba para 1 y 2023 son los únicos que se aprobaron.
Cuando probaste este código por primera vez, notaste que convertía 24 en XXIIII, lo que no era exactamente incorrecto, pero no era la forma común en la que IIII se convierte en IV. Todas las pruebas fallidas fueron para casos similares. Cuando se observó este problema por primera vez, el laboratorio dijo: "Como en realidad no es incorrecto (ten en cuenta que muchos relojes muestran 4 como número romano IIII), dejaremos ese problema para una mejora futura".
Podrías cambiar los casos de prueba para que esperen y acepten las respuestas "no tan incorrectas" que recibe el código, o bien aceptar que es hora de esa "mejora futura". Por lo tanto, tu próximo paso es corregir el código, con la ayuda de Gemini Code Assist, para que las respuestas más aceptables sean las que esperan las pruebas.
6. Mejora del código
Recuerda que las respuestas como XXIIII para 24, en lugar de la más común XXIV, se consideraron "no realmente incorrectas" y se pospusieron para una mejora futura. Ese futuro es hoy. Esas respuestas "no tan incorrectas" siguen siendo molestas.
La primera regla para los dígitos repetidos en números romanos es la siguiente: Cada vez que tengas cuatro dígitos idénticos seguidos, debes reemplazarlos por uno de los dígitos seguido del siguiente dígito más alto. Por lo tanto, XXIIII se debe reemplazar por XXIV. Del mismo modo, 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 number_to_roman la devuelva:
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:

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

Gemini Code Assist agregó más líneas para controlar los casos con los que puedes terminar después de realizar el primer conjunto de sustituciones. Por ejemplo, el 19 se convertiría en XVIIII, luego en XVIV y, finalmente, en el XIX correcto.
Si Gemini Code Assist hizo sugerencias aparentemente útiles, presiona Tab para aceptar las recomendaciones, guarda el archivo y vuelve a ejecutar el servidor web. De lo contrario, agrega las líneas que se muestran en el ejemplo de forma manual y guarda el archivo. Prueba una conversión difícil: 1999:

Correcto.
Vuelve a ejecutar las pruebas ahora. ¡Todas pasan!
Parece que la aplicación web está lista para ponerse en producción.
7. Implementa en Cloud Run
Cloud Run ejecutará una aplicación alojada en contenedores en Internet por ti. En el caso de las aplicaciones escritas con frameworks comunes, como Flash, el comando gcloud run deploy incluso compilará ese 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 se sugiere. Del mismo modo, cuando se te solicite un nombre de servicio, presiona Intro para aceptar la sugerencia.
Es posible que el comando falle porque gcloud no puede determinar qué proyecto usar. En ese caso, ejecuta el siguiente comando:
gcloud config set core/project <project-id>
donde se reemplaza por el ID de tu proyecto, que puede ser el mismo que su nombre. Luego, vuelve a ejecutar el comando gcloud run deploy.
- El comando te indicará que se necesitan ciertas APIs que aún no están habilitadas. Ingresa y para habilitarlos.
- Cuando se te solicite que selecciones una región, elige una que te resulte conveniente. Ingresar el número correspondiente a
us-central1es una opción segura. - Cuando se te pregunte, ingresa Y para continuar.
- Deberás permitir las invocaciones no autenticadas de este servicio de Cloud Run. La opción de autenticación que usa Cloud Run es adecuada para los programas que llaman al servicio. Como se trata de un sitio web, no usarás la autenticación.
Google Cloud compilará el contenedor, lo implementará, enrutará el tráfico hacia él y establecerá políticas de acceso. Luego, te mostrará el vínculo a la página principal:

Puedes ir a ese vínculo y acceder a tu solicitud.

Ingresa un número y presiona Intro. ¡Listo!

¿Qué?
¡Funcionó en tu máquina! ¿Por qué no está terminado?
Descúbrelo. Pregúntale a Gemini Code Assist,
Why am I getting an internal server error on cloud run?

Aparentemente, Gemini Code Assist puede leer el archivo de registro, que dice algo similar. Preguntémosle a Gemini Code Assist cómo puedes consultar los registros por tu cuenta:

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

A esto le siguen muchas líneas de detalles sobre la pila de llamadas que llega aquí, pero luego está esto:

Cuando mires tu archivo calendar.py, verás 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 engañosa. 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 calendar, primero buscó en el directorio de tu aplicación. Aparentemente, Python en Cloud Run buscó primero los 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 se aloja en un contenedor, lleva su entorno dentro de sí, por lo que, dondequiera que la ejecutes, puedes esperar el mismo comportamiento. Si hubieras ejecutado de forma local la misma aplicación en contenedores que tiene 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 a my_calendar.py y, luego, cambia las líneas import calendar en main.py y calendar-unittest.py a import my_calendar. Por último, cambia la línea
roman = calendar.number_to_roman(number)
a
roman = my_calendar.number_to_roman(number)
Pruébalo de forma local, ejecuta las pruebas y, luego, vuelve a implementar:
gcloud run deploy
Y ahora funciona:

Puedes compartir esta URL, y todas las personas que necesiten una herramienta de conversión de números romanos podrán usar la tuya.
8. Opcional: Haz que se vea mejor
Tu aplicación se ejecuta correctamente y cualquier persona en la Web puede acceder a ella. Pero se ve un poco simple. Antes de contárselo a todo el mundo, ¿por qué no le pides a Gemini Code Assist que mejore su apariencia?
Abre el archivo templates/index.html. En la ventana del chat de Gemini, haz la siguiente pregunta:
Make this index.html file use material design.
La respuesta consiste en agregar contenido al archivo actual, lo que generará 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 pegarlo sobre el contenido existente de 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:

Si lo deseas, puedes repetir este proceso con el archivo convert.html.
Gemini Code Assist conoce bastante sobre CSS y puede ayudarte a diseñar las páginas de la aplicación de varias maneras. Esto es solo el comienzo.
Como quieres compartir esta aplicación, no olvides volver a implementarla en Cloud Run:
gcloud run deploy
Puedes pasar la URL a las personas que necesiten convertir números 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 funcionalidad mejorada.
Cuando termines de usar la aplicación que compilaste, puedes borrarla del panel de la consola de Cloud para detener cualquier posible cargo futuro.