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 プロジェクト
- 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 を有効にすると、クエリを 1 つまたは 2 つ実行してテストできます。サンプルクエリがいくつか表示されますが、「Cloud Run とは」のようなクエリを試すことができます。

Code Assist が質問に対する回答を返します。右上の
アイコンをクリックすると、コードアシストのチャット ウィンドウが閉じます。
Cloud Shell エディタで Gemini を有効にする
Gemini Code Assist は、いくつかの一般的な IDE で利用可能であり、同様の動作をします。この Codelab では、ウェブブラウザで完全に実行される Google Cloud Shell エディタを使用します。Cloud Shell エディタで Gemini を有効にして構成する必要があります。手順は次のとおりです。
- 下に示すアイコンで Cloud Shell を起動します。Cloud Shell インスタンスの起動には 1~2 分かかる場合があります。

- [エディタ] または [エディタを開く] ボタンをクリックし、Cloud Shell エディタが表示されるまで待ちます。[新しいエディタを試す] ボタンが表示されている場合は、クリックします。

- 下のステータスバーにある [Cloud Code - Sign in] ボタンをクリックします。指示に従ってプラグインを承認します。ステータスバーに「Cloud Code - no project」と表示されている場合は、それを選択して、使用するプロジェクトのリストから特定の Google Cloud プロジェクトを選択します。

- 右下のステータスバーに Gemini アイコンが表示されない場合は、Cloud Code で有効にする必要があります。まず、IDE で Gemini(旧称 Duet AI for Developers)が有効になっていることを確認します。[Cloud Code Extension] → [Settings] に移動し、下の図のように「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 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?
レスポンスがより具体的になり、コピーして新しいファイルに挿入できる 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 チャット ウィンドウの右上隅にある二重矢印をクリックして単体テストコードを含む新しいファイルを作成するか、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 ではなく「それほど間違っていない」と判断され、今後の機能強化のために延期されたことを思い出してください。その未来が今、ここにあります。「間違っていない」回答は、やはり迷惑です。
ローマ数字の繰り返し数字の最初のルールは、同じ数字が 4 つ連続している場合は、その数字の 1 つと次の大きい数字に置き換える必要があるということです。したがって、XXIIII は XXIV に置き換える必要があります。同様に、XXXX は XL に変更し、CCCC は CD にします。
number_to_roman が値を返す直前に、roman 変数の値を変更する方法を Gemini Code Assist に尋ねます。
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 に置き換えます。プロジェクト 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 では何が異なる可能性がありますか?
答えは少し複雑です。number_to_roman 関数が定義されている calendar.py ファイルと同様に、Python3 には calendar という標準モジュールが含まれています。ローカルマシンで、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
これで動作するようになりました。

この URL を共有すると、ローマ数字変換ツールが必要なすべてのユーザーがこのツールを使用できるようになります。
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
ローマ数字に変換する必要があるユーザーに URL を渡すことができます。
9. 完了
お疲れさまでした。Gemini Code Assist を使用して、アプリケーションにテストを追加し、エラーを修正し、拡張機能を追加できました。
構築したアプリケーションの使用が終了したら、クラウド コンソールのダッシュボードからアプリケーションを削除して、将来の料金が発生しないようにします。