GSP1330

概览
Gemini 是一款 AI 赋能的协作工具,可帮助开发团队更快速、更高效地构建、部署和运维应用。
在本实验中,您将学习如何使用开发者工具 Gemini 协助调试代码,以及生成单元测试,例如测试代码中的边界条件。
本课程中的实验涵盖了从应用开发者视角出发的典型软件开发生命周期 (SDLC)。SDLC 的其他方面(要求、安全、监控等)将在其他课程中介绍。
目标
本实验的重点是使用开发者工具 Gemini 完成下列事项:
- 在开发者工具 Gemini 的帮助下发现并解决运行时错误。
- 为函数生成单元测试。
学习内容
Cymbal Superstore 是一个蓬勃发展且在不断完善的在线购物平台。为了保持市场竞争力,他们设计了一项名为“New Products”的新功能,目的是让用户可以轻松发现商店库存中的最新商品。

新端点 newproducts 已部署到预演环境,但并没有完全达到他们的预期。您的任务是对新代码进行修改和调试。为了让您可以集中精力学习如何利用开发者工具 Gemini 为您提供帮助,新代码将会添加到原始代码库中。您还需要为后端服务编写一些单元测试。
设置和要求
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。为此,我们会向您提供新的临时凭据,您可以在该实验的规定时间内通过此凭据登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的互联网浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式(推荐)或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
注意:请仅使用学生账号完成本实验。如果您使用其他 Google Cloud 账号,则可能会向该账号收取费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个对话框供您选择支付方式。左侧是“实验详细信息”窗格,其中包含以下各项:
- “打开 Google Cloud 控制台”按钮
- 剩余时间
- 进行该实验时必须使用的临时凭据
- 帮助您逐步完成本实验所需的其他信息(如果需要)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示“登录”页面。
提示:将这些标签页安排在不同的窗口中,并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在“实验详细信息”窗格中找到“用户名”。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在“实验详细信息”窗格中找到“密码”。
-
点击下一步。
重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭据。
注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
继续在后续页面中点击以完成相应操作:
- 接受条款及条件。
- 由于这是临时账号,请勿添加账号恢复选项或双重验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需访问 Google Cloud 产品和服务,请点击导航菜单,或在搜索字段中输入服务或产品的名称。
激活 Cloud Shell
Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。
-
点击 Google Cloud 控制台顶部的激活 Cloud Shell
。
-
在弹出的窗口中执行以下操作:
- 继续完成 Cloud Shell 信息窗口中的设置。
- 授权 Cloud Shell 使用您的凭据进行 Google Cloud API 调用。
如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 Project_ID 。输出内容中有一行说明了此会话的 Project_ID:
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud 是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
- 点击授权。
输出:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南。
任务 1. 调查、生成和测试代码
设置环境变量
- 在 Cloud Shell 中运行以下命令以设置必要的环境变量。
export PROJECT_ID=$(gcloud config get-value project)
export REGION={{{project_0.default_region|Lab Region}}}
export ZONE={{{project_0.startup_script.lab_zone|Lab Zone}}}
- 运行以下命令,将必要文件从 Cloud Storage 存储桶复制到 Cloud Shell。
gsutil -m cp -r gs://duet-appdev/cymbal-superstore .
调查代码
Gemini 不仅能解释您不熟悉的代码段,还能为您创建注释,方便您将注释添加到代码中,以便在未来的维护周期中更好地理解代码。
- 在 Cloud Shell 窗口右上角点击 Open Editor(打开编辑器)选项,以打开编辑器。

系统将打开 Visual Studio Code 编辑器。您可以使用 Cloud Shell 菜单栏中的选项在新窗口中打开编辑器。
- 依次前往 File(文件) > Open Folder(打开文件夹)…。

- 选择 cymbal-superstore 目录,然后点击 OK(确定)。


现在,所选文件夹应该会显示在 Visual Studio Code 编辑器的 Explorer 部分。

-
打开 backend 文件夹下的 index.ts 文件。
-
在文件右上角点击 Gemini
旁的箭头。
-
点击 Select Gemini Code Assist Project(选择 Gemini Code Assist 项目),选择要在哪个项目中使用 Gemini。从列表中选择 项目 ID。


- 如果编辑器底部出现任何提示,指出所选项目未启用 Gemini Code Assist,请点击提示中的 Enable API(启用 API)按钮以启用该 API。

生成代码
- 在 index.ts 文件中,滚动到第
102 行,您会看到以下文本:/newproducts endpoint code goes here。
将这一行替换为下面的注释。
{{{project_0.startup_script.prompt_1 | "Comment 1"}}}
{{{project_0.startup_script.prompt_2 | "Comment 2"}}}
- 选择新添加的注释,然后点击出现的黄色灯泡图标。点击列表中的选项:
Gemini: Generate code。

- Gemini 将显示建议的代码。查看建议的代码,然后点击 Accept(接受)或按 Tab 键接受。代码应当如下图所示。

注意:
- Gemini 知道“are in stock”的含义。这是一个相当容易理解的短语,就是正常的字面意思,因此 Gemini 在这里使用了它。如果您的要求不太常见,可能需要提供示例。
- 由于使用了名为“quantity”(数量)的数据属性,Gemini 能够将其与“in stock”(有货)的概念相关联。如果您使用简写、缩写或其他非标准措辞来命名变量、属性和方法,不仅会增加后期其他人维护代码的难度,还会导致 Gemini 提供的建议不够具体。
- 尽管没有明确说明,但 Gemini 建议使用数据库运行检查代码,以与文件中的其他端点保持一致。
测试代码
- 使用 Cloud Shell 窗口工具栏上的 Open Terminal(打开终端)按钮,切换回 Cloud Shell 终端。在 Cloud Shell 终端中,运行以下命令。
cd ~/cymbal-superstore/backend
npm run start
您的输出将如下所示:

- 在 Cloud Shell 窗口的工具栏上点击 + 选项,在 Cloud Shell 中打开另一个终端,并调用本地主机上的端点。
curl localhost:8000/newproducts
接着查看第一个终端中的输出,该输出显示已取消且存在错误。
您的输出将如下所示:

点击检查我的进度以验证是否完成了以下目标:
生成并测试代码。
任务 2. 使用 Gemini Chat 进行调查
-
在编辑器中打开 index.ts 文件。
-
打开 Gemini Chat(如屏幕截图所示),并在提示中输入给定的错误消息。
{{{project_0.startup_script.prompt_2_1 | "Error message to be entered in the prompt"}}}

您的输出将如下所示:

注意:Gemini 每次生成的结果都不同,因此您看到的结果可能与您的在实验中看到的回答不一致。
- 检查代码以解决现有问题。您确定以下命令是错误的根源:
const query = firestore
const products = await firestore
.collection("inventory")
.where("timestamp", ">", new Date(Date.now() - 604800000))
.where("quantity", ">", 0);
.where("timestamp", ">=", sevenDaysAgo)
.where("quantity", ">", 0)
.get();
Gemini 的回答为您提供了两个选项:将过滤条件修改为等值过滤条件,或删除其中一个不等值过滤条件。
首先,我们从 Firestore 调用中移除“数量”过滤条件,以解决错误。
- 如需移除“数量”不等式过滤条件,请从 index.ts 文件中移除以下代码段。
.where("quantity", ">", 0);
可以移除此代码,使函数正常运行。数量为 0 的商品将无法从 API 响应中过滤掉,这意味着它们将无法满足业务要求,并且会失败。我们必须注意避免插入缺货商品。有几种方法可以妥善解决这个问题。为了确定哪种方法最好,我们需要 Gemini 的帮助。
- 在 Gemini 对话中提出以下问题,并确保 index.ts 文件处于打开状态。
{{{project_0.startup_script.prompt_2_2 | "Question to the Gemini Chat"}}}
您的输出将如下所示:

如果重置聊天后,Gemini 仍反复建议您添加两个“where”子句,您可以使用下面的提示来获得不同的答案。
{{{project_0.startup_script.prompt_2_3 | "Different question approach to the Gemini Chat"}}}
Gemini 通常会提供一个可供尝试的替代方案。您可能需要重置聊天并修改几次提示,才能获得非 Firestore 选项。
注意:Gemini 有时会很固执,只提供随机(且无效)的 Firestore 选项。在这种情况下,学习者只需按照建议继续学习即可。
您的输出将如下所示:

- 在 index.ts 文件中添加代码段,修改现有代码。
if (p.quantity > 0) {
productsArray.push(p);
}
修改后,代码应如下所示。

测试代码,并进行上述更改。
- 打开 Cloud Shell 终端并粘贴以下命令。
cd ~/cymbal-superstore/backend
npm run start
- 打开第二个终端标签页,并调用端点
localhost。
curl localhost:8000/newproducts
您的输出将如下所示:

- 我们来尝试另一种方法,使用内嵌注释,并移除上面添加的条件。最终代码应如下所示。

- 在 productsArray.push(p) 行之前,添加下面给出的注释。按 Ctrl+Enter 生成代码。如果返回
if (p.quantity > 0),请接受此代码。
{{{project_0.startup_script.prompt_2_4 | "Comment message"}}}
注释掉该过滤器,它应如下所示:

点击检查我的进度以验证是否完成了以下目标:
使用 Gemini Chat 进行调查。
注意:总体而言,由于修复此问题的方法有很多,Gemini 可能会提供多个建议。发生这种情况时,您必须评估这些选项。Gemini 还可能会自动对代码语法进行修正,就像上面显示的那样。
任务 3. 运行测试
- 前往 Cloud Shell 终端并执行以下命令。
cd cymbal-superstore/backend
npm run test
您的输出将如下所示:

- 打开 backend 文件夹下的 index.test.ts 文件。此文件中包含几个简单的测试,这些测试是使用名为
supertest 的工具以及 Jest 测试框架开发的。查看现有测试,并让 Gemini 解释不清楚的地方。
任务 4. 借助 Gemini 编写测试
在此任务中,您将在 Gemini 的帮助下为后端中的新 Products API 编写一个测试。
编写测试
- 打开 backend 文件夹下的 index.test.ts 文件。在文件底部添加以下注释。
{{{project_0.startup_script.prompt_3_1 | "Comment message 1 in index.test.ts"}}}
{{{project_0.startup_script.prompt_3_2 | "Comment message 2 in index.test.ts"}}}
- 选择新添加的注释,然后点击出现的黄色灯泡图标。在列表中点击选项:
Gemini: Generate code(Gemini:生成代码)。按 Tab 键接受建议。
这是生成的代码示例。您也可以粘贴下面给出的代码。
describe('GET /newproducts', () => {
it('should return a 200 status code', async () => {
const response = await request(app)
.get('/newproducts');
{{{project_0.startup_script.prompt_3_3 | "Generated code line from Gemini"}}};
});
it('should return a list of new products with length 8', async () => {
const response = await request(app)
.get('/newproducts');
expect(response.body.length).toBe(8);
});
});
运行测试
- 在 Cloud Shell 终端中执行以下命令。
cd ~/cymbal-superstore/backend
npm run test
您的输出将如下所示:

- 滚动终端输出中的结果,看看是哪个测试失败了。

注意:您应该会看到此响应,表明测试失败。值 10 是新产品数量,包括数量为 0 的产品。根据新的业务要求,应过滤掉缺货的商品,但测试表明存在问题。
点击检查我的进度以验证是否完成了以下目标:
为新的 Products API 编写测试。
修复 bug
- 打开 backend 文件夹下的 index.ts,移除上一个任务中添加的过滤条件的注释。更新后的代码应如下所示。
//do not insert products that are out of stock
if (p.quantity > 0)
productsArray.push(p);
- 从 Cloud Shell 终端重新运行测试。
cd ~/cymbal-superstore/backend
npm run test
您的输出将如下所示:

任务 5. 边界条件测试
边界条件测试的难度可能比较大,因为需要考虑各种意外情况,例如空列表或负余额。这些情况不应该发生,但可能会在执行过程中出现。我们来看看,Gemini 能否在这种情况下提供帮助。
- 为了提供最通用的回答,请关闭所有打开的文件。点击对话窗口上方的新对话图标 (+) 重置 Gemini 对话,然后输入以下提示:
{{{project_0.startup_script.prompt_4_1 | "Prompt for boundary conditions"}}}
您的输出将如下所示:
Yes, I can definitely help you create tests for boundary conditions!
Boundary value analysis is a crucial part of software testing.
It involves testing at the "edges" or "boundaries" of input domains.
These are often the places where errors lurk.
To help you best, I'd need a little more information. For example:
- What programming language are you using?
- Could you provide the code (or a snippet of it) that you'd like to test?
- What are the inputs and their expected valid ranges?
- 打开
backend 文件夹下的 index.ts 文件,为 Gemini 提供一些背景信息。向 Gemini 询问有关 /newproducts 端点的边界测试。打开 Gemini 的聊天功能,然后输入:
{{{project_0.startup_script.prompt_4_2 | "Prompt for boundary tests for the /newproducts endpoint"}}}
您的输出将如下所示:

注意:显然,其中一些边界条件是根据代码本身(过去 7 天内添加且有货)生成的,还有一些是 Gemini 根据此类代码的典型特性,自动补充的。这对于开始创建一组可靠的边界条件非常有用。
- 如需将其转换为实际测试,请打开 index.test.ts 文件。复制下面的注释并将其添加到文件末尾。
{{{project_0.startup_script.prompt_4_3 | "Comment message in index.test.ts file"}}}
您的输出将如下所示:

- 在 index.test.ts 文件中,在上述注释后添加以下代码。
describe('GET /newproducts', () => {
it('should not return products that are out of stock', async () => {
const response = await request(app)
.get('/newproducts');
response.body.forEach((product: any) => {
expect(product.quantity).toBeGreaterThan(0);
});
});
});
- 在 Cloud Shell 终端中重新运行测试。您应该会看到如下输出。
您的输出将如下所示:

点击检查我的进度以验证是否完成了以下目标:
边界条件测试。
恭喜!
在本实验结束时,您将能够熟练地利用开发者工具 Gemini 来增强代码调试功能,并简化单元测试的生成,尤其是在评估代码中的边界条件时。
上次更新手册的时间:2025 年 10 月 17 日
上次测试实验的时间:2025 年 10 月 17 日
版权所有 2025 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。