1. 簡介
在本實驗室中,您將使用 Google Cloud 的 AI 輔助協作工具 Gemini Code Assist,為現有的 Python 網頁應用程式新增測試,並找出及修正測試發現的應用程式錯誤。接著,您會使用 Code Assist 為新功能建立測試,並生成程式碼來通過這些測試,進而擴充應用程式。
執行步驟
- 您將使用 Cloud Shell 編輯器下載現有網頁應用程式的程式碼。
- 您將在 Cloud Shell 編輯器中使用 Gemini Code Assist Chat,詢問有關 Google Cloud 的一般問題。
- 您將在 Cloud Shell 編輯器中使用 Gemini Code Assist 內嵌程式碼輔助功能,為應用程式產生測試、執行測試、找出並修正錯誤,然後擴充應用程式的功能。
課程內容...
- 如何使用 Gemini Code Assist 執行多項開發人員工作,例如生成測試和程式碼。
- 如何使用 Gemini Code Assist 瞭解 Google Cloud。
事前準備
- Chrome 網路瀏覽器
- Gmail 帳戶
- 已啟用計費功能的 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 控制台視窗會在控制台右側開啟。如果下方顯示「啟用」按鈕,請點選該按鈕。如果沒有看到「啟用」按鈕,而是看到 Chat 介面,表示您已為專案啟用 Gemini for Cloud,可以直接前往下一個步驟。

- 啟用後,你可以試著詢問 Gemini 一兩個問題。系統會顯示幾個查詢範例,但您可以嘗試「什麼是 Cloud Run?」等問題。

程式碼輔助工具會回覆問題的答案。按一下右上角的
圖示,即可關閉 Code Assist 即時通訊視窗。
在 Cloud Shell 編輯器中啟用 Gemini
Gemini Code Assist 支援多種熱門 IDE,且運作方式類似。在本程式碼研究室中,您將使用 Google Cloud Shell 編輯器,這個編輯器完全在網路瀏覽器中執行。您需要在 Cloud Shell 編輯器中啟用及設定 Gemini,步驟如下:
- 透過下圖所示的圖示啟動 Cloud Shell。啟動 Cloud Shell 執行個體可能需要一到兩分鐘。

- 按一下「編輯器」或「開啟編輯器」按鈕 (視情況而定),等待 Cloud Shell 編輯器顯示。如果看到「試用新版編輯器」按鈕,請點選該按鈕。

- 點選底部狀態列中的「Cloud Code - Sign in」按鈕,如下圖所示。依指示授權外掛程式。如果狀態列顯示「Cloud Code - no project」,請選取該項目,然後從專案清單中選取要使用的特定 Google Cloud 專案。

- 如果右下方的狀態列未顯示 Gemini 圖示,請在 Cloud Code 中啟用。請先前往「Cloud Code Extension」→「Settings」,然後輸入「Duet AI: Enable」,確保 Gemini (舊稱「開發人員專用 Duet AI」) 已在 IDE 中啟用,如下所示。確認已選取核取方塊。請重新載入 IDE。這會啟用 Cloud Code 中的 Gemini,且 IDE 中會顯示 Gemini 狀態列。

- 如圖所示,點選右下角的「Gemini」按鈕,然後選取已啟用 Cloud AI Companion API 的正確 Google Cloud 專案。

- 選取 Google Cloud 專案後,請確認狀態列的 Cloud Code 狀態訊息中已顯示該專案,且狀態列右側也已啟用 Gemini,如下所示:

現在可以開始使用 Gemini Code Assist 了!
3. 下載並檢查應用程式
在終端機視窗中,執行指令來複製存放區 (內含起始程式碼),然後切換至新目錄 (如果終端機視窗已關閉,請點選「Terminal」或「Open Terminal」按鈕來還原):
git clone https://github.com/GoogleCloudPlatform/testing-with-duet-ai-codelab.git
cd testing-with-duet-ai-codelab
在編輯器中開啟 main.py,然後點選編輯器左側的 Gemini Chat 圖示,開啟 Gemini Chat 視窗。這個 Gemini Chat 視窗位於 IDE 中,可將 IDE 中的程式碼做為討論的背景資訊。輸入提示詞「解釋這個」,然後查看答案:

你可以捲動這個對話視窗,查看完整答案。說明指出,我們可以在終端機視窗中執行 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 專為此目的設定的 Proxy 伺服器。效果與在本機執行完全相同。
歡迎立即試用!輸入 25,然後按下「Convert!」

沒錯,25 的羅馬數字是 XXV!你必須完成這項操作。
請再檢查幾個號碼。25 歲可以,24 歲呢?

或許我們有點操之過急,以為一切安好。XXIIII 是 24 的正確轉換嗎?應該是 XXIV 吧?
XXIIII 可能是正確的,但這並非一般人預期的結果。但這其實不算是錯誤 (請注意,許多時鐘會以羅馬數字 IIII 表示 4),因此請將這個問題留待日後改善。
不妨試試負數,零?羅馬數字無法表示這些數字。使用者似乎沒有收到任何回覆,這可能是需要解決的錯誤。
測試有助於找出並排除錯誤,而 Gemini Code Assist 可協助我們編寫及使用測試。
5. 新增測試
返回 Gemini Chat 視窗,然後詢問
How can I test the number_to_roman function?
詳閱回覆,其中應包含 unittest 模組和 pytest 模組的討論內容。
您可能希望 Gemini Code Assist 實際為您編寫這些測試。在編輯器中開啟 calendar.py (實際轉換程式碼所在位置),返回 Gemini Chat 視窗,然後再次詢問
How can I test the number_to_roman function?
現在的回覆內容更加具體,甚至還包含可複製或插入新檔案的單元測試模組:
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 的基礎模型會不時更新,因此答案不一定相同。如果看到不同的程式碼集,現在可以選擇是否要繼續使用本程式碼實驗室中顯示的範例 (複製這裡顯示的程式碼),也可以試試 Gemini Code Assist 現在提供的替代答案。如有時間,甚至可以嘗試這兩種做法。Gemini Code Assist 是程式設計助理,可依您的需求使用。
按一下 Gemini Chat 視窗右上角的雙箭頭,建立含有單元測試程式碼的新檔案,或使用 IDE 建立新檔案,然後貼上本實驗室顯示的程式碼。在該視窗中按下 Ctrl-S 或 Cmd-S 鍵儲存檔案,並將儲存的檔案命名為 calendar-unittest.py。
返回終端機並按下 CTRL-C 鍵,停止先前執行的網路伺服器,然後取得殼層提示。輸入指令
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 鍵接受建議、儲存檔案,然後再次執行網頁伺服器。否則,請手動新增範例中顯示的行,然後儲存檔案。嘗試困難的轉換:1999 年:

答對了!
現在請重新執行測試。全部通過!
網頁應用程式似乎已準備好投入生產。
7. 部署至 Cloud Run
Cloud Run 會在網際網路上為您執行容器化應用程式。如果是使用 Flash 等常見架構編寫的應用程式,gcloud run deploy 指令甚至會在部署容器前為您建構容器。執行下列指令:
gcloud run deploy
在終端機中。系統詢問原始碼位置時,請按下 Enter 鍵,接受系統建議的正確位置。同樣地,當系統要求輸入服務名稱時,請按 Enter 鍵接受建議。
由於 gcloud 無法判斷要使用哪個專案,因此指令可能會失敗。在這種情況下,請執行下列指令:
gcloud config set core/project <project-id>
其中 會替換為專案 ID,這可能與專案名稱相同。然後重新執行 gcloud run deploy 指令。
- 指令會提示您需要某些 API,但尚未啟用。輸入 y 即可啟用。
- 系統要求選取區域時,請選擇方便的區域。輸入與
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 Console 資訊主頁刪除,以免日後產生任何費用。