こんにちは、AGESTのバックエンドエンジニアのまさです。
今回は、CursorエディタのComposer機能を用いて、AIにテストコードを記述してもらう方法をご紹介します。テストコードはソフトウェアの品質を高めるために重要ですが、手作業で書くのは時間がかかるものです。そこで、AIの力を借りて効率的にテストコードを生成してみましょう。
具体的な手順やコード例を交えながら、詳しく解説していきます。
※今回ご紹介するCursor Composerは現時点ではPro版でないと使用できないようですので、その点だけご注意ください。なお、Free版には2週間のPro版トライアルがついています。
【参考】Cursor Pricing(価格表)
Cursorエディタとは
Cursorは、VSCodeをフォークしたAI活用型の新しいコードエディタです。VSCodeユーザーであれば、馴染みのあるインターフェースと操作性で、移行しても違和感なく利用できます。コード補完機能やリファクタリング支援など、開発者の生産性を向上させるための機能が豊富に備わっています。Composer機能を使うことで、コード全体の分析やコードの自動生成が可能です。
環境構築
Cursorのインストール
まずは、公式サイトからCursorをダウンロードし、インストールします。
インストール後、Cursorを起動します。
Cursor起動後、ユーザー設定 > Cursor Settingsを開きます。
設定メニュー内の「Features」内のComposerをenabledに設定します。
プロジェクトの準備
テスト対象のコードを用意します。ここでは、Go言語を使用した例を示しますが、他の言語でも同様の手順で進められます。
example/
├── main.go
└── utils/
├── example.go
└── item.go
テスト対象のコード作成
まずはテストに使用する構造体をutils/item.go
に実装します。
package utils
// Item構造体を定義します
type Item struct {
ID int // アイテムのID
Name string // アイテムの名前
Price int // アイテムの価格
}
次にテスト対象となる関数をutils/example.go
に実装します。
// utilsパッケージに含まれるユーティリティ関数を定義します
package utils
// ItemsTotalPriceは、与えられたItemスライスの合計価格を計算します
func ItemsTotalPrice(items []Item) int {
total := 0 // 合計価格を初期化
// 各アイテムの価格を合計に加算
for _, item := range items {
total += item.Price
}
return total // 合計価格を返却
}
Composer機能を使ったテストコードの自動生成
テストコードを生成する手順
example.go
ファイルをCursorで開きます。Ctrl + i
をキー入力します。 CursorのComposerの入力画面が表示されます。
- 入力ファイルの「+」を押下し、item.goを追加します。
- プロンプトに「ItemsTotalPriceに対するテストコードを作成してください。」と入力します。
- ComposerがAIを利用してテストコードを生成します。
生成されたテストコードの確認
自動生成されたテストコードは以下のようになりました。
import (
"testing"
)
/**
* TestItemsTotalPrice は ItemsTotalPrice 関数のテストを行います。
*
* このテストでは、以下のケースを確認します:
* 1. 空のスライスの場合
* 2. 1つのアイテムを含むスライスの場合
* 3. 複数のアイテムを含むスライスの場合
*
* @param t *testing.T テストを実行するためのテストオブジェクト
*/
func TestItemsTotalPrice(t *testing.T) {
// テストケースを定義
testCases := []struct {
name string
items []Item
expected int
}{
{
name: "空のスライス",
items: []Item{},
expected: 0,
},
{
name: "1つのアイテム",
items: []Item{
{ID: 1, Name: "アイテム1", Price: 100},
},
expected: 100,
},
{
name: "複数のアイテム",
items: []Item{
{ID: 1, Name: "アイテム1", Price: 100},
{ID: 2, Name: "アイテム2", Price: 200},
{ID: 3, Name: "アイテム3", Price: 300},
},
expected: 600,
},
}
// 各テストケースを実行
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// ItemsTotalPrice関数を呼び出し
result := ItemsTotalPrice(tc.items)
// 期待される結果と実際の結果を比較
if result != tc.expected {
t.Errorf("期待される結果: %d, 実際の結果: %d", tc.expected, result)
}
})
}
}
テストコードの解説
- アイテムが空の場合: 空のスライスを渡した場合に合計が0になるかを検証。
- アイテムが1つの場合: 単一のケースで合計価格が正しく計算されるかを検証。
- アイテムが複数の場合: 通常のケースで合計価格が正しく計算されるかを検証。
それぞれのケースで、期待される合計価格と実際の結果を比較し、不一致があればエラーメッセージを出力します。
コードの実登録
上記で確認したテストに問題がなければ「Accept all」を押下します。
再度Ctrl + i
キーを押下すると、エディタ画面に復帰すると、utilsディレクトリ配下にutils_test.goが作成されていることが確認できます。
テストコードの実行
ターミナルで以下のコマンドを実行し、テストを確認します。
go test ./...
すべてのテストがパスすれば成功です。
Composer機能の利点
- 入力ファイルの複数指定:Composerの大きな利点はここにあると思います。実は今回のようなケースではgithub copilotでも同様のことは実現できます。ただし実際に実用的な良いコードを生成しようとするならば単一のファイルやコードを入力に生成することは難しく、プロジェクト内の多様なソースを複数参照したうえで生成する必要があります。このCursorのComposerであれば複数のファイルを入力に指定できるため、必要な入力を全て与えることが可能です。
- ファイルの生成:既存の生成AIではコードを画面に出力することはできても実際にファイルを生成するということはできませんでしたが、Cursorであれば提案された内容のファイルをそのまま出力してくれます。
- ファイルの修正の提案:処理の修正が必要なとき、そのまま書き換えてしまうのではなく修正候補として表示され、キー入力により同意することで反映されるようになっています。一つ一つの修正内容をしっかりと確認した上で、提案を適用しやすくなっています。
おわりに
CursorのComposer機能を活用することで、テストコードの作成が格段に効率化されます。特に、複数のファイルを入力させることにより、今までよりもずっと実用的なコード生成が可能となっています。
また、今回はあくまでテストコードの生成としてご紹介しましたが、もちろんメインのコードの生成も可能です。仕様をプロンプトに入力しコード生成させることでメインのソースを組み立てていくことができますし、既存の処理の修正も可能です。もちろん最終的には自身の目でレビューする必要があるということは他のAIツールと同様です。
今後もAIツールを積極的に活用し、開発効率とコード品質の両立を目指していきたいと思います。