在前一篇測試中, 我們利用提示詞讓 Gemini CLI 生成程式碼, 正確地透過 API 取得給定地址的郵遞區號, 但是生成的程式是手動另開 DOS 或 PS 視窗執行的, 其實也可以叫 Gemini CLI 幫我們測試, 它會幫我們尋找本機的 Python 環境來執行, 本篇旨在接續先前靠一張嘴寫程式的方法, 叫 AI 測試它自己寫的程式.
本系列之前的測試文章參考 :
首先進入專案目錄執行 gemini :
PS D:\gemini> cd postal-helper-proj1
PS D:\gemini\postal-helper-proj1> gemini
然後輸入 /res 或 /resume 恢復之前的對話, Gemini CLI 會找出之前的 session 列表, 可以上下移動選擇要恢復的對話後按 Enter (此處只有編號 1 的對話) :
輸入 :
> 請幫我測試程式是否正確
Gemini CLI 這次找了一個台中的地址, 執行結果為找不到, 所以它寫了一個 test_api.py 的測試程式, 要求儲存程式檔 :
接著要求執行測試程式 test_api.py :
測試程式執行時出現錯誤, 它會自行檢查原因與修正, 它發現需修改 postal-helper.py 原始碼, 要求授權 :
接著修正測試程式 test_api.py :
執行結果程式已正常, 但查詢台灣大道 99 號結果仍然找不到, 可能是地址有改, 它打算換別的地址測試來測試 :
改用中港路二段99號就順利傳回郵遞區號了 :
以上的 Gemini CLI 測試中都是使用系統 Python 來執行程式, 如果 Gemini CLI 找不到 Python 執行環境就會出現錯誤. 目前最新的 Python 版本管理工具是 uv 工具, 它整合了 Python 版本, 套件安裝, 以及虛擬環境管理於一體, 使用上比傳統 pip + venv 方便許多, 參考 :
接下來輸入 "我使用 uv 工具" 提示詞看看 Gemini CLI 如何利用 uv 來執行測試, 首先它會初始化 uv 專案, 建立專案描述檔 pyproject.toml :
接著它會編輯 pyproject.toml, 加入腳本定義, 以便能用 uv run 來執行腳本 :
接下來它要求授權修改 postal-helper.py 腳本 :
程式已改好, 要求授權用 uv run 執行腳本, 傳入地址參數為台北市信義區市府路 1 號 :
uv run 指令執行成功, 取得正確 6 碼郵遞區號 110204 :
最後, 我把 Gemini CLI 修改過的 postal-helper.py 抄錄如下 :
import sys
import json
import urllib.parse
import urllib.request
import io
# 確保在 Windows 上輸出為 UTF-8
if sys.platform == "win32" and isinstance(sys.stdout, io.TextIOWrapper) and sys.stdout.encoding != 'utf-8':
try:
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
except (AttributeError, io.UnsupportedOperation):
pass
def get_postal_code(address):
base_url = "https://zip5.5432.tw/zip5json.py"
params = {'adrs': address}
# Ensure the URL is correctly encoded
url = f"{base_url}?{urllib.parse.urlencode(params)}"
try:
# User requested 6-digit postal code
print(f"正在查詢地址: {address} ...")
req = urllib.request.Request(url)
# Some APIs require a User-Agent
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) PostalHelper/1.0')
with urllib.request.urlopen(req) as response:
if response.status != 200:
print(f"錯誤: API 返回狀態碼 {response.status}")
return
data = response.read()
try:
result = json.loads(data)
except json.JSONDecodeError:
print("錯誤: 無法解析 JSON 回應。")
print(f"回應內容: {data.decode('utf-8', errors='ignore')}")
return
# The API returns 'zipcode6' for the 6-digit code.
# Sometimes it might return an empty string or null if not found.
zip6 = result.get('zipcode6')
if zip6:
print("-" * 30)
print(f"地址: {result.get('address', address)}")
print(f"6碼郵遞區號: {zip6}")
print("-" * 30)
else:
print("找不到該地址的 6 碼郵遞區號。")
# Show full result just in case useful info is elsewhere
if 'error' in result:
print(f"API 錯誤: {result['error']}")
except urllib.error.URLError as e:
print(f"網絡錯誤: {e}")
except Exception as e:
print(f"發生未預期的錯誤: {e}")
def main():
if len(sys.argv) > 1:
# Join arguments to handle addresses with spaces if not quoted
address_input = " ".join(sys.argv[1:])
get_postal_code(address_input)
else:
# Interactive mode
print("台灣 6 碼郵遞區號小幫手 (uv 版)")
print("用法: uv run postal-helper <地址>")
print("或在下方輸入地址 (按 Ctrl+C 離開):")
while True:
try:
address_input = input("\n請輸入地址: ").strip()
if not address_input:
continue
get_postal_code(address_input)
except KeyboardInterrupt:
print("\n程式結束。")
break
except EOFError:
break
if __name__ == "__main__":
main()













沒有留言 :
張貼留言