1. 简介
在本实验中,您将使用 Google Cloud 中 AI 赋能的协作工具 Gemini Code Assist,为现有的 Python Web 应用添加测试,并查找和修复测试发现的应用错误。然后,您将使用 Code Assist 为新功能创建测试,并生成代码以通过这些测试并扩展应用。
实践内容…
- 您将使用 Cloud Shell 编辑器下载现有 Web 应用的代码。
- 您将使用 Cloud Shell 编辑器中的 Gemini Code Assist Chat 来询问有关 Google Cloud 的常见问题。
- 您将使用 Cloud Shell 编辑器中的 Gemini Code Assist 内嵌代码助理来为应用生成测试、运行测试、查找和修复错误,然后扩展应用的功能。
学习内容…
- 如何使用 Gemini Code Assist 执行多项开发者任务,例如生成测试和生成代码。
- 如何使用 Gemini Code Assist 了解 Google Cloud。
所需条件…
- Chrome 网络浏览器
- Gmail 账号
- 启用了结算功能的 Cloud 项目
- 为您的 Cloud 项目启用了 Gemini Code Assist
本实验的适用对象为各种水平的开发者,包括新手。虽然示例应用采用 Python 语言,但您无需熟悉 Python 编程即可了解其运行原理。我们的重点是让开发者熟悉 Gemini Code Assist 的各项功能。
2. 设置
您应该已经有一个启用了结算功能的 Cloud 项目,可用于本实验。我们现在将在 Google Cloud 项目中启用 Gemini API。请按下面给出的步骤操作:
- 访问 https://console.cloud.google.com,并确保您已选择计划用于本实验的 Google Cloud 项目。点击右上角显示的 Gemini 图标。

- Gemini for Cloud 控制台窗口会在控制台右侧打开。点击下方显示的启用 按钮。如果您没有看到启用 按钮,而是看到聊天界面,则表示您已为项目启用 Gemini for Cloud,可以直接进入下一步。

- 启用后,您可以向 Gemini 提出一两个查询,以测试 Gemini。下方显示了几个查询示例,不过您可以尝试诸如什么是 Cloud Run? 之类的查询

Code Assist 会回答您的问题。您可以点击右上角的
图标,关闭 Code Assist 聊天窗口。
在 Cloud Shell 编辑器中启用 Gemini
Gemini Code Assist 在多种主流 IDE 中均可用,且行为类似。在此 Codelab 中,您将使用 Google Cloud Shell 编辑器,它完全在您的网络浏览器中运行。您需要在 Cloud Shell 编辑器中启用和配置 Gemini,相关步骤如下所示:
- 通过如下所示的图标启动 Cloud Shell。启动 Cloud Shell 实例可能需要一两分钟的时间。

- 点击编辑器 或打开编辑器 按钮(视具体情况而定),然后等待 Cloud Shell 编辑器出现。如果您看到试用新编辑器 按钮,请点击该按钮。

- 如图所示,点击底部状态栏中的 Cloud Code - 登录 按钮。按照说明对插件进行授权。如果您在状态栏中看到 "Cloud Code - no project" ,请选择该选项,然后从项目列表中选择您打算使用的 Google Cloud 项目。

- 如果您在右下角的状态栏中没有看到 Gemini 图标,则需要在 Cloud Code 中启用该图标。在执行此操作之前,请确保已在 IDE 中启用 Gemini(以前称为 Duet AI for Developers),方法是前往 Cloud Code 扩展程序 → 设置 ,然后输入文本 Duet AI: Enable ,如下所示。确保选中此复选框。您应重新加载 IDE。这将在 Cloud Code 中启用 Gemini,并且 IDE 中会显示 Gemini 状态栏。

- 点击右下角的 Gemini 按钮(如图所示),然后选择已启用 Cloud AI Companion API 的正确 Google Cloud 项目。

- 选择 Google Cloud 项目后,请确保您能够在状态栏的 Cloud Code 状态消息中看到该项目,并且在状态栏右侧看到已启用 Gemini,如下所示:

Gemini Code Assist 已准备就绪,可供使用!
3. 下载并检查应用
在终端窗口中,运行以下命令以克隆包含起始代码的代码库,然后切换到新目录(如果终端窗口不再打开,请点击终端 或打开终端 按钮以恢复该窗口):
git clone https://github.com/GoogleCloudPlatform/testing-with-duet-ai-codelab.git
cd testing-with-duet-ai-codelab
在编辑器中打开 main.py ,然后点击编辑器左侧的 Gemini 聊天图标 ,打开 Gemini 对话 窗口。此 Gemini Chat 窗口位于 IDE 中,并且 IDE 中的代码可用作讨论的上下文。输入提示 Explain this 并查看答案:

您可以滚动此聊天窗口以查看整个答案。说明中指出,我们可以在终端窗口中使用命令 python3 main.py 在本地运行此程序。
4. 在本地运行
如果需要,请使用 cd ~/testing-with-duet-ai-codelab 切换到代码库目录,然后在终端窗口中输入命令 python3 main.py:

点击链接 http://127.0.0.1:8080,打开新的浏览器标签页以访问应用的主页:

应用正在“本地”运行。实际上,Cloud Shell 编辑器在这里做了一些神奇的事情。应用在 Cloud Shell 中运行,而不是在您自己的计算机上运行。当您点击该链接时,它打开的标签页不是实际的本地地址 http://127.0.0.1:8080,而是 Cloud Shell 专门为此目的设置的代理服务器。效果与您在本地运行该应用完全相同。
试试看。输入 25 ,然后按 Convert!

没错,25 的罗马数字是 XXV!您必须在此处完成操作。
不妨再检查几个数字。25 可以正常转换,那么 24 呢?

也许我们认为一切正常有点操之过急了。XXIIII 是 24 的正确转换吗?不应该是 XXIV 吗?
有人可能会认为 XXIIII 是正确的,但它并不是人们通常期望的形式。不过,由于它实际上并没有错(请注意,许多时钟将 4 显示为罗马数字 IIII),因此我们将此问题留待日后改进。
不妨尝试一下负数?零?无法用罗马数字表示这些数字。用户似乎没有收到任何返回内容,这看起来像是一个需要解决的错误。
测试有助于查找和消除错误,而 Gemini Code Assist 可以帮助我们编写和使用测试。
5. 添加测试
返回 Gemini 对话窗口,然后提问
How can I test the number_to_roman function?
通读回答,其中应包括对 unittest 模块和 pytest 模块的讨论。
您可能希望 Gemini Code Assist 实际为您编写这些测试。在编辑器中打开 calendar.py(实际转化代码所在的位置),返回 Gemini 对话窗口,然后再次提问
How can I test the number_to_roman function?
回答现在更加具体,甚至包含您可以复制或注入到新文件中的 unittest 模块:
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")
您可能会看到与上述示例不同的代码。Gemini Code Assist 的底层模型会不时更新,因此答案并不总是相同。如果您看到一组不同的代码,现在可以选择是复制此处显示的代码以继续使用此 Codelab 中显示的示例,还是尝试 Gemini Code Assist 现在给出的替代答案。如果您有时间,甚至可以尝试这两种方法。Gemini Code Assist 是一款编码助理,您可以根据需要使用它。
您可以点击 Gemini Chat 窗口右上角的双箭头,创建一个包含单元测试代码的新文件,也可以使用 IDE 创建一个新文件,然后粘贴本实验中显示的代码。在该窗口中按 Ctrl+S 或 Command+S 以保存该文件,并将保存的文件命名为 calendar-unittest.py。
返回终端,然后按 Ctrl+C 停止之前运行的 Web 服务器,并获取 shell 提示符。输入命令
python3 calendar-unittest.py
以运行新测试。
没有输出。这与预期不符。一切都静默通过了吗?您想确定这一点。回顾一下 Gemini Code Assist 的回答,其中包含测试代码。在代码下方,有关于如何运行测试用例的更多信息:

尝试运行推荐的命令:
python -m unittest discover
如果您的机器没有将 python3 命令别名为 python,则可能会出现问题,在这种情况下,请运行:
python3 -m unittest discover
该命令运行,但返回 Ran 0 tests in 0.000s。该模块包含多个测试。发生了什么?
是命令中的最后一个字 discover。它从哪里来的?显然,Gemini Code Assist 希望将测试代码保存在名为 discover 或 discover.py 的文件中,但没有指定您应该这样做。由于您实际上将文件保存在 calendar-unittest.py 中,因此请尝试运行以下命令:
python3 -m unittest calendar-unittest
现在,您会看到大量输出,以类似如下的内容开头:
$ 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
第一行显示通过的每个测试用句点,以及失败的每个测试用 F。大多数测试都失败了!然后,它会单独列出失败的测试,显示预期输出和实际输出。这些测试的运行顺序有点不清楚。它是按测试名称的字母顺序运行的,而不是按测试在文件中出现的顺序运行的。因此,test_convert_1 首先运行,然后是 test_convert_1990,然后是 test_convert_2023,依此类推。1 和 2023
的测试用例是唯一通过的测试用例。
当您首次尝试此代码时,您注意到它将 24 转换为 XXIIII,这并不完全错误,但不是将 IIII 转换为 IV 的常见形式。所有失败的测试都是针对类似情况的。首次注意到此问题时,实验室指出:“不过,由于它实际上并没有错(请注意,许多时钟将
4 显示为罗马数字 IIII),因此我们将此问题留待日后改进。”
您可以更改测试用例,以预期并接受代码给出的“实际上并没有错”的答案,或者接受现在是进行“日后改进”的时候了。因此,您的下一步是借助 Gemini Code Assist 帮助修复代码,以给出测试期望的更可接受的答案。
6. 增强代码
回想一下,对于 24,XXIIII 等回答(而不是更常见的 XXIV)被认为是“实际上并没有错”,并被推迟到日后改进。现在就是日后。这些“实际上并没有错”的答案仍然令人烦恼。
罗马数字中重复数字的第一条规则是:当您连续有四个相同的数字时,应将它们替换为其中一个数字,后跟下一个更高的数字。因此,XXIIII
应替换为 XXIV。同样,XXXX 应更改为 XL,CCCC 应变为 CD。
问问 Gemini Code Assist 如何以这种方式更改 roman 变量的值,就在 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?
建议是在末尾添加一些代码:

在编辑器中复制/粘贴或输入这些行,然后查看会发生什么:

Gemini Code Assist 添加了更多行来处理您在进行第一组替换后可能遇到的情况。例如,19 将转换为 XVIIII,然后转换为 XVIV,最后转换为正确的 XIX。
如果 Gemini Code Assist 给出了明显有用的建议,请按 Tab 键接受建议,保存文件,然后再次运行 Web 服务器。否则,请手动添加此处示例中显示的行,然后保存文件。尝试一个困难的转换:1999:

回答正确!
现在重新运行测试。所有测试都通过了!
Web 应用似乎已准备好投入生产环境。
7. 部署到 Cloud Run
Cloud Run 将在互联网上为您运行容器化应用。对于使用常见框架(例如 Flash)编写的应用,gcloud run deploy 命令甚至会在部署之前为您构建该容器。运行以下命令:
gcloud run deploy
在终端中。当系统询问源代码的位置时,请按 Enter 键接受其建议的正确位置。同样,当系统询问服务名称时,请按 Enter 键接受建议。
该命令可能会失败,因为 gcloud 无法确定要使用的项目。在这种情况下,请运行以下命令:
gcloud config set core/project <project-id>
其中 替换为您的项目 ID,该 ID 可能与项目名称相同。然后重新运行 gcloud run deploy 命令。
- 该命令会提示您需要某些 API,但尚未启用。输入 y 以启用这些 API。
- 当系统要求您选择区域时,请选择一个方便您的区域。输入与
us-central1对应的数字是一个安全的选择。 - 当系统询问时,输入 Y 以继续。
- 您需要允许对此 Cloud Run 服务进行未经身份验证 的调用。Cloud Run 使用的身份验证选项适合调用该服务的程序使用。由于这是一个网站,因此您不会使用身份验证。
Google Cloud 将构建容器、部署容器、将流量路由到容器并设置访问政策,然后向您显示主页的链接:

您可以访问该链接并访问您的应用。

输入一个数字,然后按 Enter 键,然后…

什么?!
它在您的机器上运行成功了!为什么还没有完成?
找出原因。问问 Gemini Code Assist,
Why am I getting an internal server error on cloud run?

显然,Gemini Code Assist 可以读取日志文件,其中显示了类似的内容。问问 Gemini Code Assist 如何自行查看日志:

继续执行此操作。查找带有红色 !! 错误指示器的行,如下所示:

接下来是许多关于调用堆栈到达此处的详细信息行,但随后是:

当您查看 calendar.py 文件时,您会看到 number_to_roman 函数!您知道它是正确的,因为它在您的机器上运行成功了。Cloud Run 中可能有什么不同?
答案很棘手。Python3 中包含一个名为 calendar 的标准模块,就像定义了 number_to_roman 函数的 calendar.py 文件一样。在本地机器上,当 Python 查找名为 calendar 的模块时,它首先搜索您的应用目录。显然,Cloud Run 上的 Python 首先查找标准模块,导入该模块,但未找到 number_to_roman 函数。
环境中的这类差异总是可能存在的。幸运的是,当应用容器化时,它会在其中携带其环境,因此无论您在何处运行它,都可以预期相同的行为。如果您在本地运行与 Cloud Run 相同的容器化应用,则会遇到相同的问题。
解决此问题。您需要将本地日历模块的名称更改为不是标准模块名称的名称。将 calendar.py 文件重命名为 my_calendar.py,然后将 main.py 和 calendar-unittest.py 中的 import calendar 行更改为 import my_calendar。最后,更改行
roman = calendar.number_to_roman(number)
至
roman = my_calendar.number_to_roman(number)
在本地试用,运行测试,然后重新部署:
gcloud run deploy
现在可以正常运行了:

您可以分享此网址,所有需要罗马数字转换工具的人都可以使用您的工具。
8. 可选:让它看起来更漂亮
您的应用运行良好,并且网络上的任何人都可以访问。但它看起来有点普通。在您告诉大家之前,为什么不问问 Gemini Code Assist 来改进其外观呢?
打开 templates/index.html 文件。在 Gemini 对话窗口中,提问:
Make this index.html file use material design.
回答是在当前文件中进行添加,从而生成类似以下内容:
<!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>
使用该图标复制建议的代码,并粘贴到 index.html 的现有内容上。在终端中,运行 python3 main.py
并点击链接以打开预览窗口。该页面现在看起来不那么普通了:

您可以根据需要对 convert.html 文件重复此操作。
Gemini Code Assist 了解很多 CSS,您可以让它以各种方式帮助您设置应用页面的样式。这只是一个开始。
由于您想分享此应用,请不要忘记将其重新部署到 Cloud Run:
gcloud run deploy
您可以将网址传递给需要转换为罗马数字的人。
9. 恭喜!
恭喜!您已成功使用 Gemini Code Assist 为应用添加测试、修复应用中的错误并添加增强功能。
使用完您构建的应用后,您可以从 Cloud 控制台信息中心将其删除,以停止任何潜在的未来费用。