Amazon CodeWhispererでGo言語のテストコード生成してみた!
はじめに
みなさんこんにちは!最近は葡萄味のグミが好きなhiropyです。
今回は、「Amazon CodeWhisperer(以下CodeWhisperer)でもテストコードが生成できるのか?」気になったので検証してみました!
最近ずっとホットな生成系AIによるコードアシスタント機能の波に乗ってみようと思います。
やりたいこと
今回の検証でやりたいことは、「Go言語で書かれた関数に対して、CodeWhispererで単体テストのコードを生成する」です。
事の発端はこちらの記事でCodeWhispererでのテストコード生成に言及されていたのが気になったからなのですが、せっかくなら勉強中の言語でもできるのか試したい!ということでGo言語を選択しました。
前提
今回は以下を前提とします。
- 筆者はGo言語を勉強し始めて1ヶ月
- 初心者でもテスト関数を予想しやすいFizBuz関数にする
- ローカルで実行してテストが成功するかを確認する
- すでにGo言語の動作環境がセットアップされている
FizBuz関数とは、「3が入力されたら"fiz"を、5が入力されたら"buz"を、3と5の公倍数が入力されたら"fizbuz"を、それ以外は入力された数値をそのまま返す関数」です。
やってみる
CodeWhispererの導入
今回はVSCode上でCodeWhispererの動作検証を実施しました。
VSCode上でCodeWhispererを有効にするためには、まずVSCodeのAWS Toolkit for VS Code
拡張機能をインストールします。
画面下部にスクロールすると、BuildersIDで始めるかIAM Identity Centerで始めるかのボタンが表示されるので、今回は「BuildersID」を選択します。
こちらは無料で利用できます。詳細はこちらのドキュメントをご覧ください。
ブラウザ上でサインインや認証処理が完了するとCodeWhispererが利用できるようになります。
なお、VSCode上で他のサジェストツールを利用している場合は一時的にツールを無効化してください。
(私はTabnineと競合してしまいました、、)
サンプル関数の作成
早速サンプルとなる関数を作成します。
まずはプロジェクトをセットアップします。
任意のディレクトリ内で以下のコマンドを実行してください。
go mod init <ディレクトリ名>
同じディレクトリ内にmain.go
ファイルを作成します。ディレクトリ構造は以下のようになります。
<任意のディレクトリ>
├── go.mod
├── main.go
このmain.go
内にコードを記載していきます。
今回は以下のFizBuz関数をテスト対象とします。以下のコードをmain.go
にコピペしてください。
package main
import (
"flag"
"fmt"
"strconv"
)
func check_fizbuz(n int) string{
if n%15 == 0 {
return "fizbuz"
} else if n%3 == 0 {
return "fiz"
} else if n%5 == 0 {
return "buz"
} else {
return strconv.Itoa(n)
}
}
func main() {
var (
i = flag.Int("i", 0, "int flag")
)
flag.Parse()
fmt.Println(check_fizbuz(*i))
}
ちなみにですが、こちらのcheck_fizbuz
関数を作成する際もCodeWhispererのサジェストを参考にしました。
fizbuz()と関数名を書いただけで関数の処理をサジェストしてくれます、、!
念の為動作確認をします。以下のコマンドを実行して、意図した値が返ってくるかを確認してください。
go run main.go -i 3 # fizが返ってくる
go run main.go -i 5 # buzが返ってくる
go run main.go -i 15 # fizbuzが返ってくる
go run main.go -i 11 # 11が返ってくる
テストコードを生成してみる
では本題のテストコード生成に取り掛かります!
まずはテストコードを記載するためのファイルを作成しますmain.go
と同じディレクトリ内にmain_test.go
ファイルを作成してください。
ディレクトリ構成は以下のようになります。
<任意のディレクトリ>
├── go.mod
├── main.go
├── main_test.go
ここまで準備できたら、どのようなコメントを入れたら意図したテストコードを生成してくれるか試していきます。
まずは、ファイルに何も記載しない状態で以下のコメントを入力してみます。
// make a test code for main.go
、、これでは流石に何もコードが生成されませんでした。
次に、packageとimportの定義のみをした状態でコメントを入力してみます。
定義は以下のように記載しました。
package main
import (
"testing"
)
コメントは以下のコメントを入力します。
// 入力値に対し3の倍数ならfiz, 5の倍数ならbuz, 3と5の公倍数ならfizbuzを返す関数のテストコード
コピペせず手入力してみたのですが、、途中まで入力した状態でコメントごとサジェストされました!
コメントの内容や意図が少し異なったので、先ほどのコメントを最後まで入力してみます。
いい感じのコードがサジェストされているように見えます!
サジェストされたコードの全文がこちらです。
testCases := []struct {
input int
output string
}{
{3, "fiz"},
{5, "buz"},
{15, "fizbuz"},
{4, "4"},
}
// テストケースごとにテストを実行
for _, tc := range testCases {
output := fizbuz(tc.input)
if output != tc.output {
t.Errorf("fizBuz(%d) = %s, want %s", tc.input, output, tc.output)
}
}
テストの対象になる関数名が異なっていたので、fizbuz -> check_fizbuz(正しい関数名)に修正しました。
書かれているテスト内容としては、3,5,15,4を引数として渡して関数を実行して、それぞれ期待する値が返ってくるかをチェックしています。期待する値も正しいですね。
この状態でテストを実行してみます。
go test .
実行すると以下のようにテストが成功します。
ok go-fizbuz 0.428s
このように、日本語のコメントであっても意図した通りにテストコードを生成してくれることが分かりました!
まとめ
いかがでしたでしょうか?
今回の検証を通して私が感じたことは、
- CodeWhispererは無料で利用できるので、無料でここまでサジェストしてくれるのは便利
- ただし、100%完璧なコードを生成するのは困難&ある程度プロンプト(コードに記載するコメント)を工夫して書く必要がある
- 個人で新しい言語をサクッと勉強するときには活躍しそう
- コメントでやりたいことを書く -> 生成されたコードで分からない箇所を調べるを繰り返すと効率よく勉強できそう
です。
無償でここまで、さらにAmazon Qでのチャット機能もあるのは非常に魅力的だと思うので、まずは個人の勉強の用途で活用できそうですね!
今後ともCodeWhispererの可能性を調査していこうと思います。