以下の内容はhttps://yattom.hatenablog.com/より取得しました。


生成AIを利用した開発の最近の自分のようす

開発というともっぱら個人開発をしており、そこで生成AIを使っていますが、最近の自分自身の使い方やツール選び、ワークフローと言うと大袈裟な感じがしますがそういう進め方について、メモしておこうと思います。2025年11月~2026年2月くらい時点のはなしです。

メモなのでたいへんに長くなりました。こちらは Gemini どんによる簡単なまとめです。生成AIを「~どん」と呼ぶのも最近のようすです (読みにくくなるので文中では呼び捨て)。

この記事は、個人開発における生成AI(主にClaude CodeやGemini)の活用手法について、2025年11月から2026年2月時点の状況を記録したものです。コーディング、テスト、設計、レビューなど多岐にわたるタスクをAIに依頼する際の「コンテキストの構築方法」や、作業内容に応じた「委託と伴走の使い分け」について、実際のプロジェクトの事例を交えて解説しています。

また文末に書いたまとめを、ここにも載せておきます。

生成AIにやってもらうこと

  • コーディング・実装
    • 仕様を実装、テストしてもらう
    • UI修正、見た目の調整
    • Issueへの対応とPull Requestの作成
    • 曳光弾開発をお任せ。AWS Amplify、CDK、外部サービスへの接続など一気に
  • テスト・環境構築
    • テスト駆動開発をする
    • ユニットテストを書く、書けるようにリファクタリングする
    • ユースケースシナリオを元に Playwright でE2Eテストを書く
    • E2Eテスト用の実行環境を作る。LocalStack、Dockerコンテナなど
  • 設計・要件定義
    • 設計の選択肢を作ってもらう。モジュール構成、サービス選定、テーブル設計など
    • 選択肢を比較評価するための観点出しと、評価のサポート
    • アーキテクチャを検討し、ADR (Architecture Decision Record) に書き残してもらう
    • ユースケースシナリオのバリエーションの追加
    • セキュリティ上確認すべき項目の整理
  • レビュー・ドキュメント作成
    • Pull Requestや実装したコードのレビュー
    • 人間の「仕様の理解」や「相談した内容の認識」のレビュー
    • 仕様変更や設計追加に伴うドキュメントの更新・同期
    • 長くなったチャットの議論を残す (Issue、ADR、仕様書など)
    • スキルやサブエージェント作成
  • 相談相手、頼れる先輩
    • 仕様の判断や、見落とし・落とし穴の検証
    • 既存コードの説明や、サンプルコードを作る
    • 一般的な知識の把握や、よくわからない技術の解説
    • 相談途中で論点を整理する。まだわからないこと、判断ポイントなど
    • 作業の進め方の相談相手と、TODOリストの作成

生成AIの参加スタイル:

  1. 自分 (人間) ができる、完成形を100%想像できること → 一発でやってもらう
  2. 情報や検討が必要、わからない点があること → 選択肢を作ってもらう
  3. それ以外 (何がわからないかわからない、など) → 伴走してもらって相談する

さらに NotebookLM によるまとめも作ってみました。一般向けに共有していますが、NotebookLM 自体にログインしないと見られないようです。

文中で例として示しているのは以下の、私の個人プロジェクトのコードや作業の様子です。

なお記事本文には生成AIの書いたテキストは利用していません。箇条書きのまとめは生成AIに書いてもらったものを手直ししました。NotebookLM によるまとめは生成AIによるものです。

Claude Code中心

コードを書くことや、それだけでなく設計の相談やレビューは Claude Code が中心です。普通のチャットは Gemini も常用していて、一般的な議論や知識の把握にはこちらを使うことも多いです。

自分のルール設定

AGENTS.md に自分とのコミュニケーションで大事なことと、開発中も常に意識してほしいこと (シンプル重視など) をごく短く書いています。CLAUDE.md には AGENTS.md を見る指示だけ書いて、AGENTS.md に自分のルールを書いていますが、これはほかの CLI も試していた関係で、Claude だけだったら不要でしょう。Copilot も見てくれると思います。

CLAUDE.md:
# Guideline for Claude Code

You must read @AGENTS.md first before reply anything.
AGENTS.md:
# Chat with user

- Use Japanese language even if the user provides English input.
- Refer to the user as やっとむ.
- Reply in a clean, unambiguous, friendly but not too-casual, to-the-point and yet kind manner.  Use 常態 not 敬体.
- Ask a lot of questions to understand user's intent correctly.  Do not guess.
...

AGENTS.md を読んだ Claude Code

AGENTS.md に自分とのコミュニケーションで大事なことと、開発中も常に意識してほしいこと (シンプル重視など) をごく短く書いています

プロジェクトの情報は README.md に書いています。プロダクトの内容、利用するコマンド、前提条件などです。人間に見てもらうつもりで書いていますが、生成AIも参照してくれるようです。

スキルとサブエージェント

Claude Code にはスキルという機能があって、独立したひとまとめの知識を別途ロードできるように書いておけます。現在はそんなに活用しておらず、テスト駆動開発 (TDD) のスキル、git コミットコメントのスキル、ADRの書き方のスキルを使っています。スキル自体は生成AIに手伝って書いてもらいましたが、生成AIが書いたスキルはあまり有用ではないという研究もあるようです。また数日前にAnthropic公式のスキル作成スキルが更新されたという話も見かけました。

またプロジェクト独自のビルドチェーンやコマンドの使い方も、スキルに書いています。

サブエージェントはスキルに似ていますが、スキルは知識としてロードされるのに対し、サブエージェントは新しいエージェントを起動して作業を委譲する仕組みです。仕事に必要な知識とコンテキストだけを使うので、全体のトークン消費をおさえられるそうです。こちらもあまり使っておらず、コードレビューのサブエージェントを作って使っています。

一般的な知識でも、プロジェクト固有の知識でも、人間と共有すると役立つようなことは生成AIと共有しても役立つと思うので、スキルなどで明示しています。またこれはリポジトリで管理します。複数のプロジェクト、複数のプロジェクトで重複して管理することになるのが気になりますが、今はうまいやり方がわかっていません。適宜コピーしています。

スキルなどはプロジェクト横断 (ホームディレクトリ) とプロジェクト固有 (プロジェクトのディレクトリ) に置けるので、共通のものはホームに置いてもいいようです。

一般的な知識でも、プロジェクト固有の知識でも、人間と共有すると役立つようなことは生成AIと共有しても役立つと思うので、スキルなどで明示しています

またプロジェクト独自のビルドチェーンやコマンドの使い方も、スキルに書いています。

すべてはコンテキスト

生成AIに作業を依頼するときには、依頼するときに渡す情報=コンテキストがたいへん重要です。プロンプトもコンテキストの一部ですが、読んでほしいファイルやドキュメント、参照してほしい情報も重要なコンテキストです。またチャット上でのこれまでのやり取り全体もコンテキストです。

ひとつのまとまった作業を依頼するとき、その作業に関連する情報をチャットのやり取りで渡したり、相談しながら詳細を決めたりして、作業に有用なコンテキストを積み上げます。話が長くなるときは、いったんそこまでの話をドキュメントとしてファイルに書き出してもらい、必要に応じて人間が手直しして、それをあらためてコンテキストに含めるということもします。既存のAPIを使うときは、そのAPIの仕様や使い方の説明ドキュメントなどを的確に渡すことも意識します。

ひとつのまとまった作業を依頼するとき、その作業に関連する情報をチャットのやり取りで渡したり、相談しながら詳細を決めたりして、作業に有用なコンテキストを積み上げます。

Claude Code には plan mode があります。コードやドキュメントの修正のような、既存の内容をいったん把握するのが大事なときは、plan mode に切り替えて必要な情報を収集して作業専用のコンテキストを作ってくれます。また、テスト駆動開発のスキルでは docs/plan.md に詳細な手順 (テストリスト) を書いてから進めるように指示してあり、このスキルで仕事を進めてもらうと同じように的確なコンテキストを作ってくれます。plan mode の内容は直接編集できないので、 人間もさわれるファイルに書いてもらう方が便利かもしれません。

GitHub 上の Copilot と Claude Code

GitHub には Copilot がいろいろと組み込まれているので、適時使っています。 今のところは PR に対して Copilot にレビューしてもらうというのがもっぱらです。 特にプロンプトを書かずにレビューしてもらっているので、精度はほどほどですが、あからさまな問題を見つけてくれることがあるので、採用しています。 実装も頼めますが、なんとなく Claude Code のほうを信頼しています。

また GitHub リポジトリに Claude Code を呼んで設計や実装、レビューもしてもらえます。デフォルトだとすべての Pull Requests に Claude Code のレビューが走り、なによりトークン消費が激しいので、明示してコメントで呼び出したときだけ実行するように修正しています。

.github/workflows /claude-code-review.yml の修正箇所

Issue や Pull Request のコメントで @claude を呼び出すと、作業を依頼できます。Issue の場合は、作業が終わったあとで「Create PR」をクリックして対応する Pull Request を作成します。

Claude Code に Issue に対応してもらう

なんでも生成AIを使うが、委託と伴走を使い分ける

さて、ある意味本題の、生成AIになにをしてもらうかの話です。基本的にはなんでもやってもらう、というか参加してもらいますが、参加のスタイルがいろいろあります。自分でもあまり整理できていないのですが、いくつかのルールという形で意識していることがあります。

まず簡単なのが、小規模な作業で、自分で作業したらほぼ悩まずに終わる、最初から完成系のイメージがだいたいわかっている場合です。ロジックのバリエーション追加、項目の変更、見た目の調整など。つまり、自分でできる、自分にとって簡単な作業。これは一発のプロンプトで指示をして、完成したら軽く確認する。典型的な委託作業です。特に渡すコンテキストを調整する必要もありません。テストも書いてもらうので、テストコードを見れば結果は大体把握できます。

こうした一発の作業は、どんどん Issue に書いていってつぎつぎに並列で進めてもらいます。並列しすぎるとマージで手間取ることはあるので、そこはほどほどに。10分とかで終わるので、そんなに同時並列することもないと思っています。ところで複数の PR のマージもまとめて依頼できそうな気がしますが、自分で結果確認するタイミングが入るので、いまのところ全部任せにはしていません。してみてもいい気はします。

自分でできる、自分にとって簡単な作業。これは一発のプロンプトで指示をして、完成したら軽く確認する。典型的な委託作業です。

正解を求めない その1・選択肢を作ってもらう

自分で作業するとしたら、あるていど考えたり調べたり、試行錯誤したりする仕事があります。だいたい見当はついているけれど、わからないところもある。こうすればできるかもしれないし、あっちのほうがいいかもしれない。そうした仕事を生成AIにそのまま依頼すると、なにがしかの判断が裏で行われることになります。その判断は正しいかもしれないが、間違っているかもしれない。また正しいとしても、人間のほうが正しいかどうか判断できないかもしれません。

そんなときには生成AIに選択肢を作ってもらいます。こうして単に仕事を進めるだけでなく、人間が仕事の進行についていけるようにします。生成AIの成果をどれだけ人間が把握しておく必要があるかは、よくわかりません。私は自分がわかっておきたいと思ったときには選択肢を作ってもらい、自分で比較評価し、比較評価自体も生成AIと相談したり観点を補ってもらったりしつつ、自分の判断として方針を決めます。選択肢を見ていると、もっと良いアイデアが出てくることもよくあります。このへんの話は2025年の講演スライドにまとめたので、そちらも参考にしてください。

自分で作業するとしたら、あるていど考えたり調べたり、試行錯誤したりする仕事があります。そんなときには生成AIに選択肢を作ってもらいます。明示的に「いくつか選択肢を出してください」と頼みます。

www.docswell.com

選択肢がほしくなるのは、主に仕様あるいはやりたいことが決まっていて、その実現方法が固まっていない場合です。いわゆる「設計」をこれからするぞ、というときですね。ロジックやアルゴリズムについての選択肢もあれば、モジュール構成の選択肢、採用するサービス選定の選択肢、テーブル設計の選択肢など様々です。

選択肢を作るのに git worktree が便利

選択肢を作るには、普通にプロンプトで明示的に「いくつか選択肢を出してください」と頼みます。ただしこれはアイデアとか、設計の概要・方針とか、短いコード部分などに限られます。

まとまった量のコードについて、複数の選択肢を実装して見比べるのには git worktree を使います。git worktree は別々のディレクトリに別々のブランチをチェックアウトする機能です。これを使うと、並行して複数の実装をそれぞれのブランチで進めて、結果を見比べられるようになります。画面を見るとイメージが分かると思います。 git worktreeを使ったときの簡単なイメージの動画を作りました。後半の1:26から見てみてください。

Claude Code などの CLI で git worktree を使うのは一般的なので、検索すればやり方はすぐ見つかります。私は branches/wt1 などのディレクトリを、必要に応じて作ったり終わったら消したりしています。作ったときには pnpm install や .env ファイルの配置などが必要になるので、頻繁にやるならなにかサポートが欲しいところです。世の中にすでにありそう。docker compose も各 worktree 内で独立して動かせるので便利です。VSCode も git worktree に対応しているそうです。

選択肢を作ってもらうのは、アイデア出しを生成AIに委託し、すこし伴走してもらったうえで、自分の判断を元に残りを委託するという参加スタイルになります。

私は自分がわかっておきたいと思ったときには選択肢を作ってもらい、自分で比較評価し、比較評価自体も生成AIと相談したり観点を補ってもらったりしつつ、自分の判断として方針を決めます。選択肢を見ていると、もっと良いアイデアが出てくることもよくあります。

正解を求めない その2・相談しながら

選択肢を作ってもらうのも難しいときがあります。そもそもなにをしたらいいんだっけ、実現方法がさっぱり思いつかない、頭の中がいろいろもやもやしている、そんなときです。こんなときは生成AIにべったり伴走してもらい、チャットで相談しながら進めます。頭の中で整理すればできるんだけど、面倒くさい、おっくうだ…というエネルギー切れのときも、相談ならぼちぼち進める感じがします。

相談する項目は様々です。仕様の判断、見落としや落とし穴の検証、設計の方針、どのサービスやAPIを使ってどう実現するか、コードを説明してもらって理解する、コード例を出してもらう、テスト内容を考える。単に良くわからないことを教えてもらうのもいいですね。一般的な知識、情報も相談できますが、ドキュメントやコードを踏まえた質問もできます (これはコンテキストを整えることを意識するとよい。このドキュメントを見て、このコードを読んでから答えて、など)。

相談を始めるときは、チャットのセッションを初期化してコンテキストを空にしましょう。Claude Code なら /new コマンドでリセットできます (ちなみに以前のセッションには /resume で戻れるので、一時的に相談するのも大丈夫)。最初のひとことで最初に相談したいテーマを提示すると、あとで /resume するとき見分けやすいので便利ですし、そのほうが反応も的確になる気がします (LLMはプロンプトの最初と最後が重視されると言いますが、ここでも関係あるのかな? あんまりない気はしています)。セッションをリセットするとトークン消費も減らせるので、その点でも意識するといいですね。

そもそもなにをしたらいいんだっけ、実現方法がさっぱり思いつかない、頭の中がいろいろもやもやしている、そんなときです。こんなときは生成AIにべったり伴走してもらい、チャットで相談しながら進めます。

相談のしかた

相談するときはオープンクエスチョンを意識します。相談しているのは、自分でもよくわからないからなので、よくわかっていない自分が主導・誘導しないよう、生成AIにいろいろな情報、観点、見方をしてほしいわけです。

  • クローズドクエスチョン: YES/NOで答えられる質問 「〇〇でいいですか?」「問題ありますか?」「他にありますか」
  • オープンクエスチョン: 回答が無数にありえる質問 「〇〇はどうですか?」「気になる点を教えて」「他のアイデアを出してください」

自分が理解した内容を文章で説明して、それをレビューしてもらうのも有効です。生成AIに教わった内容を理解できているか、相談してきた内容について認識が合っているか、見落としや考え違いがないかなどが確認できます。生成AIにまとめてもらって終わりだと、あとで勘違いに気づくことがよくあります。

あるていど相談が進んだところで、論点をリストアップすることがあります。相談前にはよくわかっていなかったことが、徐々にわかってきます。わかってきたところで、わかったところ・まだわからないところ、判断が必要だとわかったポイント、新たな疑問点などを、途中で一覧にします。これがすべて解決したら相談は終わり、作業を進められるという判断ポイントが作れます。なんとなくわかった、納得したという感覚でなく、なにが解決したからOKなんだと明示できます。こういう話をしたときは、だいたい結論を Issue に書き残してもらうことが多いです。

相談はチャットだけで完結せず、コードやドキュメントなどを更新しながらできます。コードを少し書いてもらった上で質問するとか、話した内容をドキュメントに反映してもらいつつ関係する情報を整理してもらうとか、TODOリストを書き出してもらうとか。TDDのピンポン (人間と生成AIが交互にコードとテストを書くこと) もこの進め方の一種かもしれません。

ドキュメントの更新は忘れがち

細かい点でも仕様が変わった場合や、設計に追加変更があったときは、ドキュメントも更新する必要があります。生成AIのおかげでコードとドキュメントの同期はたいへん楽になりました。ですが生成AIのほうも調子に乗って開発していると、ドキュメントを忘れることがよくあります。人間が忘れないように意識して、ときどき確認したり、明示的に指示しています。このへんは AGENTS.md やスキルなどでワークフローをしっかり定義してあげると、意識しなくてよくなるかもしれません。まだ試したことはありません。

生成AIのほうも調子に乗って開発していると、ドキュメントを忘れることがよくあります。人間が忘れないように意識して、ときどき確認したり、明示的に指示しています。

テストはガードレールであり案内標識である

生成AIを使わなくても、現代のソフトウェア開発でテスト自動化は欠かせません。生成AIを利用するときには、自動テストの存在がさらに価値が増しています。生成AIがコードの振る舞いを意図せず変えてまうことがありますが、自動テストがあれば振る舞いの変化にすぐ気がつけます。またそもそも生成AIが正しいコードを書いているか、人間がコードを見て確認するよりも、どう動作するかを確認する方が確実ですし、時間もかかりません。プロダクトコードをすべてレビューして問題がないか探すのであれば、自動テストを書いて、そのテストの挙動を確認しましょう。多少のミスがあっても事故につながるのを防ぐ、ガードレールの役割です。

私が生成AIにテスト駆動開発を指示するようになったのは意外と最近で、2025年まではあんまりテストを書かずに進めてしまうことが多かったです。反省としては、ちゃんとTDDするときは伴走する必要があるという気がしていて、委託するときはテストは手を抜いていました。2026年からは委託するときも基本的にTDDで進めるよう AGENTS.md に記述し、そのためのスキルも設定しました。人間と生成AIがピンポンするTDDも有意義ですが、生成AI単独で進めるときもTDDが有効だと理解したのは比較的最近、というわけでした。

生成AIを利用するときには、自動テストの存在がさらに価値が増しています。生成AIがコードの振る舞いを意図せず変えてまうことがありますが、自動テストがあれば振る舞いの変化にすぐ気がつけます。

TDDのスキルの中に、ユニットテストでは外部依存を用いず、モックもできるだけ避けて、ロジックだけを抜き出してテストできるように設計する指示を入れています。これは私の志向が強く出ていますが、ユニットテストでのコードカバレッジはあまり高くせず、アプリとしての仕様を直接表現できるテストを重視しています。

.claude/skills/test-driven-development/SKILL.md (抜粋):

# Tests

- Write unit tests for TDD.
- Avoid using mocks as much as possible.
- Readability is more important in test code so avoid dependencies and over reuse and make every single test cases easy to understand just by themselves.
- Order test files and test cases so that the organized tests represents the structure of the specification.
- Make sure that unit tests does not use actual external resources like DynamoDB and also does not use mocks.  The very interface with external resources should not be tested in unit tests.  When we want to test logic we wrote, refactor them out into a separate method/function/class/module and then write unit test for them.

E2E テストは Playwright

アプリとしての動作を担保するテストは Playwright のテストを書いてもらっています。まずは仕様をまずユースケース記述やシナリオとして書いておいて、それを自動化してもらいます。ユースケースシナリオのバリエーションは生成AIに増やしてもらってもいいですね。部分的には、機能単体を確認する E2E テストもありますが、あまり増えすぎないよう気をつけています。

E2E テストは実行環境を作って維持するのが手間ですが、ここは生成AIに全面的に頼りました。もろもろのAWSサービスを LocalStack で構築し、フロントエンドもテスト実行もそれぞれコンテナにして、docker compose run でテストを実行するようにしています (説明なしでコードをシェアしても、生成AIに聞けばすぐ解説してもらえるので、シェアも気軽にできていいですね)。テスト結果はホストディレクトリをマウントしてそこに出力しています。

仕様をまずユースケース記述やシナリオとして書いておいて、それを自動化してもらいます。機能単体を確認する E2E テストもありますが、あまり増えすぎないよう気をつけています。

E2E テストを BDD や ATDD のテストと位置づけて、先にテストを書くやり方も可能だとは思いますが、実践はしていません。自分で仕様を考えて自分で作る個人開発だと、あまりメリットを感じません。生成AI向けには、ユースケースシナリオが目標としてのテストの位置づけになるように感じています。

ドキュメント上で進め方の方針を共有

plan mode を使えば、まず進め方の方針をまとめて、確認もできます。ただしいったん作業が始まると介入しにくくなります。TDDをするときには、生成AIと人間が双方でさわれるところに進め方を書いてもらっています。スキルで明示して、 docs/plan.md の中にTODOリストを書いた上で進めるよう指示しています。

docs/plan.md (抜粋):
# TODOリスト

NOTICE: TODOリストはフラットな箇条書きで、着手順に上から並べること。新しい項目もフラットに、実施順になるよう途中に挿入する。セクションを分けたり階層化するのは禁止。

- [x] README.md作成
- [x] docs/spec.md作成
...
- [x] EthicsMap: N2ノードにポイントを割り振れる (上限は親N1のポイント)
- [x] EthicsMap: ポイントを増やすとPのポイントが減り、減らすと戻る
- [x] EthicsMap: Pのポイントが0のとき他のノードのポイントを増やせない
- [x] EthicsMap: 子ノードのポイントを超える親の減少はできない
...
- [ ] ollamaClient モジュールを実装する (src/services/ollamaClient.js: 接続確認・ テキスト生成)
- [ ] F09 OllamaStatus コンポーネントを実装する (接続インジケーター)
- [ ] F08 EthicsCodeView コンポーネントを実装する (倫理綱領テキスト表示・ローディ ング)
- [ ] F08 ポイント変更時のリアルタイム生成を App.vue に組み込む (debounce付き)

実際のところはすべての開発作業をここに書きながら進めているわけではないようです。人間が忘れる場合もあり、Claude Code も忘れていたりしますが、細かい作業は GitHub Issue に残っているのでわりと関係ないです。大きな作業を計画するときには、確実にここで計画、方針を検討するようにしています。人間が見直したり、部分的に伴走に切り替えたり委託に戻したりもやりやすいです。

TODOリストはTDDのテストリストの位置づけと同じで、自分がどこに到達しようとしているのか、そのためどうやって進むのか、案内標識や目印やリマインダーとなります。同時に、自分が設計をどのように理解しているのかのバロメーターともなり、理解が中途半端なまま進もうとしたときの黄色信号の役にも立ちます。自分でテストリストを書けなかったり、テストリストの項目が理解できなかったりしたら、立ち止まる合図です。生成AIに委託しているなら、一時的にでも伴走で進めるタイミングです。

自分がどこに到達しようとしているのか、そのためどうやって進むのか、案内標識や目印やリマインダーとなります。同時に、自分が設計をどのように理解しているのかのバロメーターともなり、理解が中途半端なまま進もうとしたときの黄色信号の役にも立ちます。

Claude Code の plan mode ではファイルを更新できず、ドキュメントも書けないので、docs/plan.md にTODOリストを書くときは編集可能なモードでやってもらいます。

CLIがいちばん快適

Claude Code だけでなく、作業はWSLのシェル (Windowsターミナル) で、tmuxでウインドウやペインを分割しています。 基本構成は、Claude Code を左ペインに、右ペインは普通のシェル作業や一時的に vim を開くところ、なにか実行するときは右上に小さく開いておくかたちで、最近は安定しています。

エディタが必要なときはvimを使います (長年のvimmerですが、特に使いこなしてはいません)。 以前はIDEをメインで使っていましたし、今でも使いますが、そもそもエディタを使う場面がずいぶん減ってしまいました。 複数のファイルをエディタで眺めるときは別ウインドウで開きます。

Claude Codeがいるtmuxのメインウインドウ

正確で高速なシェル操作

シェルとCLIがいちばん反応が良く、若干非力ないまのノートPCでも快適に動きます。VSCodeやIntelliJ IDEAも使うことがありますが、開発環境がWSLだったりDockerだったりで重くなってあまり気持ちよくないです (これは環境への投資の話でもある。新PCをセットアップ中なので、今後変わるかもしれない)。

npm (pnpm) や uv、またAWS CLIなどのコマンドを繰り返し正確に実行できるのもCLIの大きなメリットです。良く使うコマンドはシェルのエイリアスや git alias を設定し、またほとんどのコマンドはシェルのヒストリから実行します。またプロジェクト独自のコマンドは、pnpm run に仕込んでいましたが見通しが悪く把握できなくなってきたので、Python Invoke に移行しようとしています

Claude Code の操作

英語キーボードで日本語IMEのキーバインドをカスタマイズしていますが、日英の切り替えがどうも煩雑に感じるため、Claude Code への指示は主に英語でしています。ややこしくて上手に書けないときは日本語で。英語で入力する方がトークン消費も少ないんじゃないかな。たぶん。

利用プランと利用量

Claude CodeのプランはProなので、まとまった作業をしているとすぐ使い切ってしまい、数時間待つことになります。業務でフルタイム開発しているなら困りますが、自分の場合・現状の範囲ではひと区切りつけられるので、まあいっかという感じです。ときどきはチャージしてある金額で追加の作業をしますが、何十ドルも一気に溶かすようなことはしていません。

Googleにも課金しているので、普通のチャットはGeminiを使っています。アーキテクチャやインフラ、設計の一般論についてはGeminiで基本を把握することも多いです。Gemini CLI も以前に試したのですが、なんとなく使っていません (理由を忘れた)。

ゼロから始めるとき

新しいソフトウェアをゼロから書き始めるということは、今まではあまりなかったと思うのですが、生成AIがある意味いちばん生きるところでもあるので、一気に増えてきている気がします。私がゼロからスタートするときは、こんな流れになっているようです。

  1. やりたいことを書き出す
    • ユーザー視点から、やりたいことを書き出す。文章でも箇条書きでもいい
    • ユースケース記述やシナリオを書く (docs/spec.md)
    • 画面の構成やデザインに注文があるなら書く。文章でも、手描きでも、Figmaでもいい
    • 利用者視点から、技術要件やアーキテクチャ要求があるときには、書き出す
      • 例: AWSを使う、静的Webアプリ、将来〇〇もサポートしたい、など
    • ここでは生成AIチャットで壁打ちしたり、アイデアを出してもらったり、全体をレビューしてもらったりします
  2. アーキテクチャを検討する
    • やりたいことを実現するのに必要な技術要素、スタック、利用サービスを整理する
    • この時点では確定せず、候補や選択肢を複数出してキープしておく
    • アーキテクチャ要求の単位でADRを書く。たいていは TBD や porposal の状態になる (docs/adr/ADR*.md)
    • ここでは生成AIにもりもり考えて、書いてもらいます。選択肢を出してもらい、さらに選択肢の評価観点も出してもらい、そのうえで選択肢を評価してもらいます。チャットで壁打ちする部分もあるし、まるっと任せる部分もあります
  3. 曳光弾開発をする
    • やりたいことから主要な要素を選び、さらにアーキテクチャの主要な要素をすべて利用する組み合わせを選ぶ。そのうえで生成AIに実装してもらう
      • ややこしく聞こえますが、要はやりたいことの技術的な実現性を確認します
    • ユーザーに見せるものではないので、機能的にも見た目的にも最小限で
    • セキュリティ上確認すべき項目も、ここで整理する
    • 自分が知らないことを確認する部分なので、生成AIに大いに委託します。できあがったものを人間が理解するためチャットなどで質問したり整理してもらったりします。実現性を確認すべきポイントについても、丁寧に相談しながら網羅します。動くのがゴールではなく、人間が理解して納得するのがゴールです
  4. ユーザーに見せられる最小限の機能を作る
    • ユーザーフィードバックを得られる最初のリリースを作る
      • どんなユーザーにどうフィードバックをもらうかで、「最小限」の量は大きく変わります
      • 仲間内でアイデアを確認するレベルなら数時間~数日、ユーザー候補に実用してもらうなら数週間になることも
      • どの機能を最初にリリースすべきかは、生成AIと相談できます
    • ここまで来ると、進め方としては普通に機能を作り足していくだけ
    • この段階では自動テストを必ず作成する
    • 生成AIにコードを書いてもらい、テストを書いてもらい、ドキュメントを更新してもらい、レビューしてもらい、Issue と PR を書いてもらいます。上で説明した、小さいから委託する /選択肢を作ってもらう / 相談しながら伴走する のモードを切り替えながら進めます

やりたいことの書き出しとアーキテクチャの検討まで進めたときの例がこちらです。

github.com

また、こちらはやりたいことをしっかり目に書いた例。

github.com

このときは、やりたいこと (プログラマーの倫理モデルを考案する) を決めるために Gemini と1週間ほど相談しました。それが決まったところからは、ユーザーに見せられるところまで、5時間くらいで進めました。

最初の1日で進めた内容

生成AIでなにが高速化するのか

これはとっても感覚的・個人的ではありますが、生成AIを使うと開発がどのくらい短縮できるのか? と思うと4割くらいかな? という気がします。つまり元の60%くらいまで縮む。イメージを図にしてみました。

開発全体は生成AIで60%くらいに短縮できる、ような?

もちろんコードを書くところ (水色の作業) の時間はかなり短縮します。いっぽう人間が関わるところ、つまり問題がなにかを見つけるところと、問題が解決したか検証するところは、基本的に変わらないです (黄色の作業)。また考える時間も、あるていど短縮するけれどそんなに劇的に「速く考えられるように」はならないなあと感じています (緑色の作業)。

あまり変わらないよね、と感じる部分を短縮しようとするのは乱暴なやり方だと思いますし、実際乱暴なやり方がこれから増えていくんだろうなと悲観してもいます。乱暴というのは、速いけれど質が悪いということです。見落とされる、切り捨てられる要素が多いということでもあります。とりわけ人間に対してしわ寄せされるんでしょうね。悲しい。

生成AIにやってもらうことと、参加スタイルの整理

最後にまとめです。

生成AIにやってもらうこと

  • コーディング・実装
    • 仕様を実装、テストしてもらう
    • UI修正、見た目の調整
    • Issueへの対応とPull Requestの作成
    • 曳光弾開発をお任せ。AWS Amplify、CDK、外部サービスへの接続など一気に
  • テスト・環境構築
    • テスト駆動開発をする
    • ユニットテストを書く、書けるようにリファクタリングする
    • ユースケースシナリオを元に Playwright でE2Eテストを書く
    • E2Eテスト用の実行環境を作る。LocalStack、Dockerコンテナなど
  • 設計・要件定義
    • 設計の選択肢を作ってもらう。モジュール構成、サービス選定、テーブル設計など
    • 選択肢を比較評価するための観点出しと、評価のサポート
    • アーキテクチャを検討し、ADR (Architecture Decision Record) に書き残してもらう
    • ユースケースシナリオのバリエーションの追加
    • セキュリティ上確認すべき項目の整理
  • レビュー・ドキュメント作成
    • Pull Requestや実装したコードのレビュー
    • 人間の「仕様の理解」や「相談した内容の認識」のレビュー
    • 仕様変更や設計追加に伴うドキュメントの更新・同期
    • 長くなったチャットの議論を残す (Issue、ADR、仕様書など)
    • スキルやサブエージェント作成
  • 相談相手、頼れる先輩
    • 仕様の判断や、見落とし・落とし穴の検証
    • 既存コードの説明や、サンプルコードを作る
    • 一般的な知識の把握や、よくわからない技術の解説
    • 相談途中で論点を整理する。まだわからないこと、判断ポイントなど
    • 作業の進め方の相談相手と、TODOリストの作成

生成AIの参加スタイル:

  1. 自分 (人間) ができる、完成形を100%想像できること → 一発でやってもらう
  2. 情報や検討が必要、わからない点があること → 選択肢を作ってもらう
  3. それ以外 (何がわからないかわからない、など) → 伴走してもらって相談する

あくまで2026年2月時点 (もう3月になってしまった!) でのメモでした。

『指輪物語 運命の旅』ソロプレイしてみました

ボードゲーム『指輪物語 運命の旅』開封し、1回ソロプレイしてみました。どんなゲームか知らず買っておいたもので、前情報もほとんどなしでしたが、久しぶりにワクワク感とドキドキ感を味わえました。ルールとかの話は基本触れずに、ゲームをやってみた体験や感じたことを簡単に紹介します。

どんなゲーム?

  • 1-5人の協力型ゲーム。今回は1人でやってみました
  • プレイ時間は60-150分ということですが、今回は開封から1回プレイして負けるまで、4時間くらいでした
  • 力の指輪を破壊すると勝利だが、その前に「目的」をいくつか達成しないといけない。まっすぐモルドールに向かえばいいわけではない
    • 目的はカードを引いて決めます。今回はカードを引くのではなくて、マニュアルにある初回プレイおすすめセットを選びました。「裂け谷でエルフを味方にする」「アイゼンガルドを占拠」「ゴンドール、ローハン、エルフの軍勢をそろえてサウロンに挑戦する」という3つの目的で、これは3つとも達成できたんですよね。
  • キャラクターもたくさんいて、プレイヤー1人で2キャラクターを動かします。今回はやはりおすすめの、フロド・サム、メリー・ピピン(これは2人で1キャラあつかい)、ガンダルフレゴラス、エオウィンでした
  • キャラクターが中つ国じゅうを駆けずり回っていろいろな条件を満たすのと同時に、軍勢を動かして拠点防衛したり攻め込んだりする要素もある。ファンタジーの王道が展開して胸熱
  • パンデミック型、ということです。私はパンデミック以外はわからないですが、ルールの理解がしやすいというくらいで、遊んだ感覚はずいぶん違った気がします

開封

箱が大きくて重いです。開けたら中身もギッシリでした。

バラドデュアを模したダイスタワーが (組み立て式)。ダイスタワーでダイス振るの嬉しいですよね。

マニュアルを読みながら1人プレイのセットアップをしました。ぜんぜんスペースが足らなかった。なんというか、中つ国の大きなマップ (ボード) に多様なコマが並んで、ナズグルが空を飛んでいるだけで、めっちゃテンション上がりますね!

黒くて大きいのは空飛ぶナズグル、小さくて赤・青・緑などがあるのは軍勢で、赤が敵、それ以外は自由の民の軍勢です。青がゴンドール、緑がエルフ、など。エドラスにはエオウィン、遠く左上 (北西) のホビット庄にフロド・サム、メリー・ピピン、ちょっと離れてガンダルフ。真ん中上の闇の森にレゴラス

敵の軍勢 (赤い小さいやつ) はカードを引いて配置するんですが、今回アイゼンガルドにすごい集まっちゃってヤバそうです。8個いるのかな。手前にエオウィンが茶色いローハン軍を連れていますが、かきあつめても3個しかいない。

旅の仲間は足が速い

ソロプレイでは1人で4キャラクター、加えてフロド・サムを動かします。4キャラクターは順番に動かせて、そのあいだにフロド・サムはちょっとずつ動かせる。誰かが活躍しているあいだにじわじわ進んでいく感じが、なかなかそれっぽいです。

とはいえ同じ場所にいるキャラクターは移動アクションで一緒に移動できるので、エリアドールにいるメリー・ピピンガンダルフがフロド・サムを連れてガンガン移動できます。ガンガン移動してすぐ裂け谷に到着。裂け谷ではハートを3つ使うとエルフが味方になるんですが、ハート?

このゲームにはリソースのようなものがあって、ハート、マント、武器、指輪の4種類があります。手札にこのいずれかがついているので、必要な時は手札で支払います。ハートがついたカードを3枚使えばいいわけです。しかし手札は上限7枚なので、思うようには集められない。そこで同じ4種類のトークンもあって、これはカードを「準備」アクションで使うとトークンに引き換えられます。安息地という、拠点みたいなところにいるときしか「準備」はできません (しばらく勘違いしてました。あとソロだと地域の縛りもある)。安息地は裂け谷とかロスロリエンとかミナス・ティリスとかそういうところ。

メリー・ピピンは特殊能力でハートを生み出せるので、カードも使って無事エルフを味方にしました。これで目的1つ達成です。さらにエルフの軍勢を招集して、しかもキャラクターと一緒に連れて行くこともできます。移動しながらどんどん軍勢を集めていけるのがダイナミック。敵軍勢と遭遇したら戦闘アクションができるんですが、戦わずにすれ違ってもいいので、ガンガン進めます (というふうにルールを理解したんだけど、合ってるのかな……?)。

というわけでアイゼンガルドをなんとかすべく、みんなでヘルム峡谷に集まったの図。エオウィンはローハン軍をじゃんじゃん招集できて、いまは5個に成長。アイゼンガルドにいた大軍勢が、いま1マス移動してます。カードによって敵軍も増えたり移動したりするんですね。

アイゼンガルド正面突破

メリー・ピピンはフロド・サムを連れてゴンドール方面に避難し、エオウィンとガンダルフでアイゼンガルドに向かいます。そしてアイゼンの浅瀬で衝突! 戦闘はダイスを振って解決します。勝ったり負けたりするんですが、ここに出た目は「ナズグル」で、一方的に被害が増えてしまいます。ところが! エオウィンには特殊能力があって、戦闘でナズグルが出てくると倒せてしまいます。ここでは1体倒しましたが、このあとすぐ2体目も倒してしまいました。アングマールの魔王は2人いたんですね。

エオウィンとガンダルフが一緒に軍勢を連れて移動しているので、戦闘の回数もふえてはかどります。さらに闇の森からエルフの弓兵を連れてレゴラスが参戦、ナズグルもめっちゃ集まってきました。レゴラスは特殊能力アクションで、敵の赤いのを1個倒したりナズグルを追い払ったりもできます。

そしてこの後、無事アイゼンガルドは占領でき、安息地となりました。敵が湧いてこなくなるのがありがたいですね (ここはパンデミックの根絶とちょっと近いのかな? でも条件がだいぶ違うなあ)。占領するときは武器リソースが必要ですが、ちょうどめくったカードに入ってて助かりました。トークンは1個も持ってなかった。アイゼンガルド占領で、2つめの目的が達成できました。なおアイゼンガルドとローハンは別領域になっていて、ナズグルが着いてこなかったので、エオウィンのナズグル狩りはできませんでした。

動かなければ見つからないが進まないと勝てない

この間メリー・ピピンはゴンドールへ逃走、フロド・サムはミナス・ティリスにずっと籠もっています。動かなければ敵に見つかる心配もないし……そうそう、フロド・サムは指輪のせいで敵に見つかる心配があるんですね。移動するとき、敵軍勢やナズグルがいると、「見つかっちゃうダイス」を振ることになります。ダイスの目によってはフロドが希望を失ってしまいます。希望がゼロになるとゲームオーバーなんですが、マントを使ってダイスをパスしたり、ハートでサムにかばってもらったりという選択肢もあって、これまた悩みどころです。

さっきはローハンのドンパチでナズグルもサウロンの目もそっちに引きつけられていて、フロド・サムにとっては動きやすかったんですね。そっちを片付けたエオウィンとガンダルフがゴンドールに入ってきたのに合わせて、フロド・サムはするっとイシリエン (オスギリアス) へ移動。敵もナズグルもいなければ、ダイスは振らなくていいのでした。

ガンダルフはゴンドール軍を集めに南へ行きました。ガンダルフは飛陰のおかげで、1人のとき足が速いのです。強い。

そして北イシリエンに大軍勢が終結。これで3つめの目的「サウロンに挑む」を達成! ゴンドール、ローハン、エルフの軍勢を決められた数連れてくるのが条件です。ガンダルフが連れてるぶんはなくてもよかった。遅れてきたガンダルフ、いえいえもちろんねらい通りに決まっている。隠れてたフロド・サムと出会えてますね (ゲーム的には意味はない)。

いよいよ滅びの山で指輪を滅ぼす……あれ、指輪持ってる?

これでモルドールの敵軍がすべてウデュンに集まり、フロド・サムの通る道ががら空きになります。この一瞬はナズグルもいないので見つかる心配なし。ただしミナス・モルグルに向かう道はマントのアイコンが2つ書いてあります。これは通るだけでマントが必要ということ。トークンとカードを貯めているけれど、滅びの山まではけっこう遠いしまだまだマントが必要だなあ。大丈夫かな。

北イシリエンに終結した自由の民の軍勢と、ウデュンの赤いかたまり。さあ総力戦だ!と思ったら、北イシリエンとウデュンの間の道はマントが4つ必要とのこと。そんなに払えないよ。敵軍も移動してこないし、なんとここで一戦も交えずにらみ合いです。戦闘にならないからサウロンの目も引きつけられないし、ナズグルもモルドールに集まってきちゃった。マントが足りないので動けないフロド・サム。

そして最後の指輪を滅ぼす条件をよく見たら、指輪リソースが5個必要とのこと。指輪リソース? そんなの持ってないぞ……と気づいたメリー・ピピン、リョバニオンからドル・グルデュア、モリアを抜けてルダウアと、トークンを集めに奔走します。いちばん危険なところを通ってないかい君たちすごいな (なおルールの勘違いをしていて、準備アクションは安息地じゃないと使えないのを無視してました)。

偉い人たちが北イシリエンで大軍勢を連れて役立たずになっているあいだ、各地を駆け回ってリソースを集めてくれたメリー・ピピンのおかげで、いよいよ滅びの山へ行ける……! と思った矢先、思わぬ展開が。敵カードの按配であまり動かないでいた敵軍勢が、カードの按配でするするっと動いて、無防備な闇の森のエルフの王国を占領してしまいました。この凶事でフロドの希望はマイナス3、一気に0=絶望に。指輪所持者は旅の半ばで心が挫けてしまい、あらぬところで「私のものだ!」と叫んでナズグルにぶら下げられて行ってしまったんでしょうね、たぶん。ゲームオーバーです。

ボード左の希望カウンターがゼロ、絶望になっています。右上の奥の方、闇の森の北に赤い軍勢がいますが、あれが敗因です。スランデュイルごめんね。

感想

指輪物語の物語を追体験するようなゲームではなく、キャラクターと目的の組み合わせに応じた様々な可能性や展開を楽しむゲームのようです。カードとサイコロの運の要素もかなり影響強そうですが、勝ちに行くというよりも、戦略を考えながら想定外の展開に対応しつつギリギリで勝てたり、勝てなかったりという、すべてを楽しむゲームですね。場面場面を楽しむゲームという気もします。

アイゼンガルドが強すぎて驚いたり、そしたらエオウィンがナズグルハンターでさらに強すぎて驚いたり、レゴラスにいいところがなかったり、ナズグルが群れをなしていたり、黒門不通でまさかのにらみ合いになったり、メリー・ピピンがとんでもない大移動をしたり、それぞれが指輪物語の世界観の中で創造力を刺激してくれるのが楽しかったです。

セットアップもたいへんだしルールも複雑で、この規模のゲームに慣れていない私にとっては難易度高かったです。ソロでやるにはだいぶ踏ん切りを付けないといけなさそう。人とやるにも説明だけでたいへん。練度の高いみなさんなら大丈夫なんだろうな。

初回でもあったためルールの勘違いや手順の混乱があって、正確なプレイにはなっていないと思います。雰囲気は掴めたんじゃないかなと思っていますが、そうでもないかもしれません。

Claude CodeでPlaywright MCPを使ってE2Eテストを書いてもらう

Playwright MCPサーバーをClaude Codeから利用して、E2Eテストを書いてみるということをしました。動いているアプリを生成AIにさわってもらいながら理解してもらい、それを元にテストを書けるんじゃないかなと思ったのがきっかけです。

できたこと:

  • Claude CodeとVSCodeのインテグレーション
  • Claude 4 Sonnetモデルを使ってみた
  • 「Webアプリを触ってみて」という指示で、どんなアプリなのか把握した
  • 「把握したことをもとにE2Eテストを書いて」という指示で、Playwright / TypeScript のテストを生成してくれた
  • Ubuntu24.04にClaude CodeとVSCode CLIをインストール、Windows 11のVSCodeから利用する (Remote - Tunnels)

うまくいかなかったこと:

  • Claude Codeが自分で書いたテストコードを、適切に直せない
  • かなり小規模なおもちゃ的アプリに対してテストが多すぎて、このまま維持するのは厳しい

Claude Codeの設定

メイン機はWindows 11 Proです。個人の事情ですが、Windows PCがパワー不足のため、開発負荷のオフロードのためUbuntu24.04のPCを併用しています。そこでClaude CodeもUbuntuに入れることにしました。以下の手順でやりました。備忘録も兼ねて、今回やりたいことと直接関係ないものも混じっています。

  • Ubuntu上の作業
  • Windows上の作業
    • Ubuntussh接続し、code tunnel でリモートサーバーを起動
      • 認証を聞かれるのでGitHubで認証
      • リモートサーバー名はホスト名になるが、これは接続時に必要になる。以下の「foo」の部分 https://github.com/login/device[2025-05-24 09:07:12] info Creating tunnel with the name: foo
    • VSCodeに Remote - Tunnels 拡張をインストール
      • ms-vscode.remote-server
    • VSCodeからリモート-サーバーに接続
      • Remote - Tunnels: Connect to Tunnel... を選ぶ
      • 実行中のリモートサーバーが一覧に出るので、選択する。上記の「foo」の部分
    • VSCodeでリモートサーバーのプロジェクトディレクトリを開く
    • VSCode上でターミナルを開く
    • ターミナルからClaude Codeをインストール
      • npm install -g @anthropic-ai/claude-code
      • claudeを実行すると、VSCodeClaude Code拡張も併せて設定される
      • ターミナルの右上に「拡張を適用するのでターミナルを開き直して」的な表示が出るので、開き直す
    • そのままターミナルでClaude Codeを実行する
      • claude
      • 最初は /init を実行するよう言われるので、実行する。CLAUDE.md ファイルができる

Playwright MCPの設定

Claude Code から Playwright MCP を使ってみたいというのが主眼なので、その設定をしました。

  • Playwright MCPをインストール
    • Cursorなどの設定ファイルに記述する例がよくあるが、Claude Codeだとわからなかったので、プロジェクトディレクトリに直接インストール (-gでグローバルにインストールするのが正解かも?)
      • npm install @playwright/mcp@latest
      • npx playwright install-deps
      • npx playwright install chrome
    • Claude CodeにMCPサーバーを追加
      • claude mcp add playwright npx @playwright/mcp@latest
      • 実はここでハマった。UbuntuGNOMEが動いていて画面があるのに、Playwright実行時に "Missing X server or $DISPLAY" や "Authorization required, but no authorization protocol specified" などのメッセージが出てエラーになる。ならばと headless にしても、なぜかずっと待たされて進まない。結論としては、Xvfbで別の仮想ディスプレイを作ってそちらを使うようにした
        • Xvfb :5 -screen 0 1600x1200x24 # 別のターミナルを開いて実行状態にする
        • DISPLAY=:5 claude
      • また、MCPサーバーのパラメーターを渡す方法にもひっかかった。途中に「--」が必要だった
        • 例: claude mcp add playwright npx -- @playwright/mcp@latest --headless

Claude CodeからPlaywright MCPを使う

設定が正しくできてしまうと、あとは簡単でした。ここから、Claude CodeでE2Eテストをするまでに試したことを書いていきます。アプリは、以前に生成AIの練習としてClineに作ってもらった個人向け金融資産管理アプリです。なおまだまともに動いていません。

まずClaude Codeに既存コードを理解してもらうために、仕様書を書いてもらいました。以下のプロンプトによって、docs/business-specification.md ができました。

ビジネス仕様書を作ってください。現在のコードから読み取れる内容を元に、特に株式と資産のデータをどの様に保存しており、どのような操作が可能かを整理してください。データベースの論理設計を記述してください (物理設計は不要)。データについては、履歴やスナップショット、過去にさかのぼった変更について、どんな操作が可能で、どんな操作は現状不可能を記載してください。ユーザーの操作については、ユーザーがどの様な要望を持っているか、どんな状況でどんな情報が得られるか、ユーザーがいつデータを更新するべきかについて、ユーザー行動の視点から整理して記述してください。機能一覧、画面一覧は不要です。ドキュメントは日本語で書いてください

プロンプトではユーザー視点を求めていますが、あまりそういう結果にはならず、機能一覧に近い内容になっていました。ただ「5.ユーザー行動とデータ更新パターン」として、ユーザーの状況やニーズを整理しているところは、がんばっている感じがします。

ここから、実際にアプリを操作してもらいました。以下のようなプロンプトです (一部省略があります)。プロンプトが日本語だったり英語だったりするのは、私の手抜きです。

実のところ、現時点で基本機能が完成していません。どこまでできているか、実際に動かして試してみてください。Playwright MCPを利用してブラウザで実際に動かせるようにしてください


start the app on Docker, use playwright mcp to navigate to the top page, take screenshot


ok, then let's check how it's working. click through all links / buttons, taking screenshots, try to operate conotrols on each page and report what functionally you touched and what happened

さてこの時点で、仕様書にあるような機能をひととおり操作した結果や、動作のおかしい部分などをまとめて出力してくれました。力作だったのですが、すみません、ここはログが残っていません。

Claude CodeにPlaywright MCPを使ってPlaywrightのE2Eテストを書いてもらう

そしてテストを実際に書いてもらうプロンプトです。基本的にはこれだけで、200件以上のテストケースが生成されました。延々と時間はかかり、料金もここだけで5USD以上使ったようです。

based on your findings write playwright tests in TypeScript in tests/e2e

この後のやり取りで、Claude Codeが自分でテストを実行して失敗したものを直すというサイクルに入り、部分的には直りました。ただし直し方が、テストの意味がない方向に倒している様子が見えたので、途中で止めました。以下のようにテストを直す (壊す?) 動きがありました。

  • 要素の存在を確認するのに、複数の要素がマッチするというエラー
    • 正しい要素を絞り込まず、1個あればOKというテストに書き換え
  • 要素の存在を確認するのに、見つからないというエラー
    • 確認するためのテストコードを消してしまう
  • 表示されている数字の値が正しくないというエラー
    • 数字の値を比較せず、なにか表示されていればOKにしてしまう
  • まだテストが落ちる
    • 実行するテストを減らして全部OKだと言う

テストは200件以上あるのですが、この様子だとテストの内容には不安があります。数字の値の比較については説明を求めたところ、まだUIのテストをしているだけでデータやロジックのテストはしていないですね、重要なので追加しましょうと素晴らしい意気込みを見せてはくれました。テストの精査と修正にも、役には立ってもらえそうです。

まとめ

動いているアプリを生成AIにさわってもらって理解してもらい、そこからテストを書いてもらうということを試しました。仕様書や設計書から生成AIがテストを書くというのはわかりますが、ドキュメントがないとき (いわゆるアジャイル開発でありがちです) どうだろう?と思って試してみました。いまの時点の結論として、できるできないで言えば、できています。

いろいろなことを初めてやってみたという段階なので、有用性についてはまだ評価ができません。引き続き人間がついていて結果を確認すること、問題があったら早めに具体的に指摘して直してもらうことは必要そうです。テストの方針を言語化して提供したり、その観点のレビューを入れるなどすると良さそうな気がします。

タイミングとしてはClaude 4が発表になってClaude Codeでも使えると聞いたので、やってみた形になります。3.7からどう変わったかは、利用シナリオが違うこともあり、あまりよくわかりません。でもClineで3.7を使うともっとループしたりしがちな気もします。

社内勉強会「ソフトウェアテストわいわい会」

本エントリはクリエーションラインアドベントカレンダー4日目の記事です。

私はアジャイルコーチとしてクリエーションライン株式会社を支援しています(2024年現在)。すでに6年ほどお手伝いしておりいろいろな形で関わらせてもらっていますが、その中でもひとつユニークな活動が「ソフトウェアテストわいわい会」です(以下、テストわいわい会)。たとえばこんなことをやっています。

  • 参加者に、自分のプロジェクトのテストの様子を共有してもらう
  • 書籍『ソフトウェアテスト技法練習帳』の問題をみんなで解く
  • 自分のプロジェクトのコードにテストを書いてみる
  • モブプロでテスト駆動開発を練習する
  • みんなで動画視聴
  • 社内JSTQBセミナーの素振り、レビューをする

参加メンバーは固定ではなく、テーマに応じて興味のある人が参加する形です。たくさん来てにぎやか、という日もあれば、2~3人の同じ顔ぶれでじっくり、という時期もあれば、あれれ誰も来ないね…というときもあったりはします。

テストわいわい会は自主参加の社内勉強会で、毎週水曜日17時から1時間実施しています。エンジニア全体に、あるいは組織として、ソフトウェアテストや品質について力を付けるため、ikikkoさんいづいづさんらが立ち上げた活動の一部になります (他にJSTQB社内セミナーや、プロジェクトのヒアリングなど)。私も初期からお手伝いしてきました。

興味のある人が集まって、興味のあることを自分たちで選んでやってみたり教え合ったりする、自律性の高い場になっています。参加していて楽しいですし、無理なく参加してもらえているようです。逆に仕事が忙しくなって参加できなくなる人が出たりするのは残念ですが、それでも会としては続けられているので、良い場になっているなあと思っています。

最近はテスト駆動開発の練習や実践をしており、そこは私の得意分野でもあって、「やっとむさんはクリエーションラインの福利厚生」というありがたい言葉を参加メンバーからいただいたりもしました。実際に仕事で扱っているコードを利用できるので、より実践的になるのが社内勉強会の良さですね。

参加メンバーからも、テストわいわい会を紹介するメッセージをいただいたので紹介します。

岡﨑岬平さん:

実務ではまだ経験のないテスト駆動開発に挑戦しています。ここで学んだことを実務に展開していくことが目標です。 参加しているみんなで相談しながら進められるので、新しい発見や気づきがたくさんありますし、詰まった時に解決策がでやすいことも魅力です。 わいわい会の名にふさわしく、みんなであーだこーだ話し合いながら進めていくのが純粋に楽しいです!

伊藤いづみさん:

「教える人」「教わる人」の構図にならずに、興味のある人が自主的に集まって題材を持ち寄ってほんとにワイワイやっているところ。私の一番好きな勉強会の形です。

山本烈也さん:

テスト駆動開発にとても関心があり、独学で本を読んで勉強しつつも実務ではあまりテスト駆動で開発をできておらず、ヤキモキした気持ちでいました。この会ではかなり実務に近い形でテスト駆動開発にまつわるいろいろなことが学べるので、プロジェクトでは実現できない気持ちを発散できていてとても楽しいです!最近はもっと発展・挑戦してBDDやってみよう!みたいな会話も生まれていて、実は社内でもかなり挑戦的な勉強会かもしれないなーなんて思っています。

これからも楽しくテストでワイワイしたい!

ソフトウェアテストというと堅苦しくなりがちな雰囲気がありますが、みんなでわいわいするのもいいですよ!

テスト駆動開発 (TDD) のテストリスト/TODOリスト作りに生成AIを使ってみよう

テスト駆動開発(TDD)ではテストリスト、あるいはTODOリストを作ります。テストリストは実現したいことの全体を網羅しつつ、問題を着手できるくらい小さな項目に分割しながら、一度に1テストずつ進めていくためのツールです。開発を一歩ずつ、1テストずつ進めながら、最後にはゴールにたどり着けるような道のりを示すものです。漫然とテストを書くだけではゴールを見失いますし、実装に夢中になっていると道を踏み外します。進む方向と進み方をセルフコントロールするためにもテストリストは重要です。

ところがテストリストを作るのは難しいものです。上手にテストリストを作るには、仕様を漏れなく重複なく分割し、さらに詳細化し、設計をイメージできるところはそれに従って項目を挙げ、イメージできない箇所は手探りで進む計画を立て、仕様に対し妥当な具体例を構築し、同時にエッジケースや例外ケースも適度に含めていき、そして想定から外れたらリストに戻って考え直すことになります。ひとつひとつ取っても経験をスキルを要しますし、いずれも見失わず総合的に考えないといけないし、さらに最初から完璧にしようとせず「進みながら考える」必要もあります。TDDを続ければ上達しますしササッと書けるようになりますが、とりわけ最初のうちは延々と悩んでしまい、時間がかかってしまうこともあります。

人間が時間をかければできる作業、これは生成AIの出番ではないでしょうか。おなじみFizzBuzz問題を使って、TDDのためのテストリストをAIに作ってもらいましょう。

プロンプト
以下のプログラミングのお題を読んでください。

「1から100までの数をプリントするプログラムを書け。ただし、3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。」

この仕様をもとに、テスト駆動開発(TDD) で進めるためのテストリストを作ってください。TDDのテストリストはインデントを用いた箇条書きで、トップレベルは全体的で、ボトムレベルは詳細で具体的になるようにします。

結果はこうでした。

ChatGPT o1-preview:
- **数をプリントする基本機能**
  - 数字をそのままプリントするテスト
    - 入力: 1、期待出力: "1"
    - 入力: 2、期待出力: "2"
- **3の倍数のときに「Fizz」をプリントする機能**
  - 3の倍数で「Fizz」をプリントするテスト
    - 入力: 3、期待出力: "Fizz"
    - 入力: 6、期待出力: "Fizz"
- **5の倍数のときに「Buzz」をプリントする機能**
  - 5の倍数で「Buzz」をプリントするテスト
    - 入力: 5、期待出力: "Buzz"
    - 入力: 10、期待出力: "Buzz"
- **3と5の両方の倍数のときに「FizzBuzz」をプリントする機能**
  - 15の倍数で「FizzBuzz」をプリントするテスト
    - 入力: 15、期待出力: "FizzBuzz"
    - 入力: 30、期待出力: "FizzBuzz"
- **1から100までの数を正しくプリントする機能**
  - ループが正しく100回実行されるテスト
  - 全ての条件を組み合わせた総合テスト
    - 入力: 1から100、期待出力: 仕様に従った結果

良さそうですね。ただし生成AIのひとたちは、FizzBuzzのような有名な問題を「知っている」ので、生成するというよりは学習データからそのまま持ってくる傾向があるようです。私が自作した、もう少し複雑な問題も試してみます。

プロンプト
以下のプログラミングのお題を読んでください。

「プレイヤー同士が1対1で対戦するシンプルなトレーディングカードゲーム(TCG)を実装してください。各プレイヤーは20のライフポイントと、固定の5枚のカードデッキを持ちます。各カードには攻撃力(1~5)が設定されています。ターン制で進行し、プレイヤーはターンごとに1枚のカードを使用して相手にダメージを与えます。ライフが0以下になったプレイヤーが敗北します。デッキのシャッフルや、ターンの管理も行う必要があります。」

この仕様をもとに、テスト駆動開発(TDD) で進めるためのテストリストを作ってください。TDDのテストリストはインデントを用いた箇条書きで、トップレベルは全体的で、ボトムレベルは詳細で具体的になるようにします。

ChatGPTとClaudeを試してみました (結果は下にあります)。いずれも全体を網羅しつつ機能要素ごとに分割してあり、なかなか良さそうです。

気になるのは着手順です。どちらも初期化を最初にしています。最終的に完成したプログラムは初期化から始まるでしょうが、TDDの最初の一手が初期化というのはあまり良くありません。初期化する対象が分かっていれば初期化できますが、まだ対象は書けていないし、分からないわけです。プレイヤーやカードがあると言われるとそういうPlayerクラスやCardクラスを作りたくなるかもしれませんが、それが問題に対し最もシンプルとは限りません。

TDDで実装と設計を進める流れとして、和田卓人さんはテスト容易性と重要度で並べ替えるよう指導しています。重要度が低いものは後回しにして良い。テスト容易なものは着手しやすいから先にやりましょう。重要だがテスト容易性が低いものは、テストしたい箇所を引きはがしてテストしやすい設計にします(Humble Objectパターン)。このように考えてリストを更新すると、手が止まらずに済みますし、着実に前進しやすくなります。

いっぽうケント・ベックは "Known to unknown" と言っています。わかるところ、自明なところから着手し、テストとリファクタリングを通じてきれいな動くコードを書きます。これは安全地帯のようなもので、仕様も設計も十分理解できていて、コードも大丈夫です。ここを土台として次の一手は、少し分からないところに進みます。分からなくなったら安全地帯に戻って、落ち着いて別の手を考えます。

どこがわかる部分で、どこがわからないかは人によって違います。唯一の正解はなく、1人ずつにとって上手くいく流れがあります。私だったらまず仕様の核心から着手し、できるだけシンプルなコードで実現して、そこから少しずつ仕様追加しながら設計を改善していきたいなあと思います。自分の仕様理解とコード設計を、ぴったり合わせながら進めたい。 このような考え方をもって、自分でテストリストを並び替えましょう。自分で考えながら、重要なもの、テストが容易なもの、わかるものとわからないものを見分けていくこと自体が、頭の中で設計を組み立てることにつながります。

とはいえテストリストを作るのは難しいものなのでした。並び順も生成AIに少しは考えてもらいましょう。そのようにプロンプトに追加します。

プロンプト
以下のプログラミングのお題を読んでください。

「プレイヤー同士が1対1で対戦するシンプルなトレーディングカードゲーム(TCG)を実装してください。各プレイヤーは20のライフポイントと、固定の5枚のカードデッキを持ちます。各カードには攻撃力(1~5)が設定されています。ターン制で進行し、プレイヤーはターンごとに1枚のカードを使用して相手にダメージを与えます。ライフが0以下になったプレイヤーが敗北します。デッキのシャッフルや、ターンの管理も行う必要があります。」

この仕様をもとに、テスト駆動開発(TDD) で進めるためのテストリストを作ってください。TDDのテストリストはインデントを用いた箇条書きで、トップレベルは全体的で、ボトムレベルは詳細で具体的になるようにします。また以下のような性質を持つように作ります。

-テストケースではなく、実装を進めるために仕様・機能を取り扱いやす大きさで切り出して並べる
-全体を網羅できるようトップレベルの項目を出してから、進める順序に応じて細分化していく
-トップレベルは、機能分割の場合と、状況や場合で分割する場合があり、適切なアプローチを選ぶ
-どうなるかわからない箇所、イメージしにくい箇所、リスクがある箇所をできるだけ早く着手する。As Kent Beck put it, "Known to Unknown, One step at a time."
- 実装するものの全体像をできるだけ早くプログラマーが把握できるように、仕様から最低限の部分を抽出して全体構成を早いタイミングで導く。よくないアプローチの例として、部品を先にすべて作ってから組み合わせる、1機能の仕様を完全に作り上げてから次の機能に進む、網羅的なテストケースを先に作ろうとする、などがある
-着手するものは具体的なテストケースにする
-各項目は説明的に、内容と意図がわかるように記述し、あまり簡潔にしない

ChatGPTとClaudeの新しい回答はこちらです。どちらもやはり、プレイヤーやカードの情報を持つところを最初に持ってくるので、初期化から着手っぽい傾向が強いようです。とはいえ情報が取得できないとテストも書けないので、このへんが最初に来るのはそれほど悪くないかもしれません。

あとは自分がやりやすいテストになるよう、生成AIとチャットを続けて修正してもらいましょう。人間とペアプログラミングするのとよく似ている感触があります。よくわからない項目は説明してもらえばいいし、順序を変えるときに理由まで伝えるとうまく整理してくれます。テストリストはTDDを進めながらどんどん更新し、変化していくものなので、そこでもときどき生成AIと相談するとよさそうです。

今回は、テスト駆動開発のテストリストを最初に書き出す部分を、生成AIに支援してもらいました。そのまま使えるかは微妙ですが、できたリストを理解したり、さらに生成AIに説明してもらったり修正したりしていくと、十分に使えるものになりそうです。

私 (やっとむ) はクリエーションライン株式会社と共同してTDDと生成AIの利活用について調査研究しており、今回のエントリはその一環です。クリエーションライン Tech Blogに同内容を掲載予定です。TDDと生成AIの活用について、一緒に試していただける方を募集しています。関心ある方はコメントをお願いします。

www.creationline.com

最初のプロンプトの結果

ChatGPT o1-preview:

  • プレイヤーの初期化

    • プレイヤーはライフポイント20で初期化されることをテストする
    • プレイヤーのデッキが5枚のカードで構成されていることをテストする
    • 各カードの攻撃力が1から5の範囲内であることをテストする
  • デッキのシャッフル

    • ゲーム開始時にデッキがシャッフルされることをテストする
      • シャッフル前後でデッキの順序が変化していることを確認する
      • デッキ内のカードが全て存在していることを確認する
  • ターンの管理

    • ゲームがターン制で進行することをテストする
    • プレイヤーが交互にターンを行うことをテストする
    • 各ターンでプレイヤーが1枚のカードを使用することをテストする
    • 使用したカードがデッキから取り除かれることをテストする
  • ダメージの計算

    • カード使用時に相手のライフがカードの攻撃力分だけ減少することをテストする
      • 例:攻撃力3のカードで相手のライフが3減ることを確認する
    • ライフポイントが0未満になった場合でも正しく計算されることをテストする
  • 勝敗の判定

    • プレイヤーのライフが0以下になったときにゲームが終了することをテストする
    • ライフが0以下になったプレイヤーが敗北することをテストする
    • 勝者が正しく判定されることをテストする
  • ゲームの流れ

    • ゲーム開始時にデッキをシャッフルすることをテストする
    • 先攻・後攻が正しく決定されることをテストする
    • プレイヤーが勝敗が決まるまで交互にターンを行うことをテストする
  • エッジケースのテスト

    • 両プレイヤーのライフが同時に0以下になった場合の処理をテストする(引き分けの判定)
    • デッキが空になった場合の処理をテストする(5ターン後にデッキがなくなるシナリオ)
  • ユーザーインターフェースのテスト(もし適用可能なら)

    • プレイヤーのライフポイントが正しく表示されることをテストする
    • 使用可能なカードが正しく表示されることをテストする
    • ゲーム終了時に勝者が正しく表示されることをテストする
  • エラーハンドリングのテスト

    • 無効なカードを使用しようとした場合の処理をテストする
    • ターン外で行動しようとした場合の処理をテストする

Claude 3.5Sonnet:

トレーディングカードゲーム テストリスト

ゲーム初期化のテスト

  • プレイヤーの初期化

    • プレイヤーが20ライフポイントで開始されること
    • プレイヤーが5枚のカードデッキを持つこと
    • 各プレイヤーのデッキが異なる順序でシャッフルされること
  • カードの初期化

    • カードが1から5の攻撃力を持つこと
    • カードが適切な識別子を持つこと
    • 不正な攻撃力のカードが作成できないこと

ゲームの進行に関するテスト

  • ターン管理

    • 最初のプレイヤーが正しく選択されること
    • プレイヤーが交互に行動できること
    • 各ターンで1枚だけカードが使用できること
    • 使用済みのカードが再利用できないこと
  • カードの使用

    • カードを使用すると相手のライフポイントが減少すること
    • カードの攻撃力分だけダメージが与えられること
    • カードを使用するとデッキから除外されること
    • 存在しないカードは使用できないこと

ゲーム終了条件のテスト

  • 勝利条件

    • プレイヤーのライフが0以下になった時点で対戦が終了すること
    • 正しい勝者が判定されること
    • 同時に両者のライフが0以下になった場合の処理
  • エッジケース

    • デッキが空になった場合の処理
    • 不正な操作(順番外でのカード使用など)が防止されること
    • ゲーム途中での状態確認が可能なこと

統合テスト

  • 一連のゲームプレイ
    • 開始から終了までの一連の流れが正常に動作すること
    • 複数回のゲームを連続して実行できること
    • ゲーム履歴が正しく記録されること

2回目のプロンプトの結果

ChatGPT o1-preview:


プレイヤーの初期化

  • プレイヤーは20のライフポイントを持つ
    • プレイヤーのライフポイントが正しく20で初期化されることを確認する
  • プレイヤーは5枚の固定デッキを持つ
    • デッキが5枚のカードで構成されていることを確認する
    • 各カードが攻撃力を持つことを確認する

カードの特性

  • カードは攻撃力を持つ
    • 攻撃力が1以上5以下の範囲内であることを確認する
    • 攻撃力が整数であることを確認する

デッキのシャッフル

  • デッキをシャッフルできる
    • シャッフル後にデッキの順序が変化することを確認する
    • シャッフルしてもデッキ内のカード枚数が変わらないことを確認する

ターンの管理

  • ゲームはターン制で進行する
    • プレイヤーが交互にターンを行うことを確認する
    • ターンの開始時に正しいプレイヤーが行動できることを確認する

カードの使用

  • プレイヤーは自分のターンに1枚のカードを使用できる
    • 手札からカードを選択して使用できることを確認する
    • 使用したカードがデッキから取り除かれることを確認する
    • 同じターンに複数のカードを使用できないことを確認する

ダメージの適用

  • カードの攻撃力分だけ相手にダメージを与える
    • 相手プレイヤーのライフポイントが正しく減少することを確認する
    • ダメージ計算が正確に行われることを確認する

ライフポイントの管理

  • プレイヤーのライフポイントが0以下になった場合の処理
    • ライフポイントが0になった場合に敗北が判定されることを確認する
    • ライフポイントが負の値にならないように制御することを確認する

勝敗の判定

  • ライフポイントが0以下のプレイヤーが敗北する
    • 勝者が正しく判定されることを確認する
    • ゲーム終了時に結果が表示されることを確認する

ゲームの進行

  • 全体のゲームフローが正しく動作する
    • ゲーム開始から終了まで一連の流れが途切れないことを確認する
    • デッキがなくなった場合の処理を確認する

デッキの管理

  • デッキからカードを引く際の処理
    • デッキが空の場合にカードを引けないことを確認する
    • デッキから正しくカードが引かれることを確認する

エッジケースの検証

  • 不正な値や状態への対処
    • 攻撃力が範囲外のカードが存在しないことを確認する
    • プレイヤーのライフポイントが不正な値にならないことを確認する

ユーザーインターフェース

  • プレイヤーへの情報提示
    • 現在のライフポイントとデッキ枚数が表示されることを確認する
    • ターンの進行状況がわかるように表示されることを確認する
    • 使用可能なカードの情報が表示されることを確認する

入力と操作

  • プレイヤーがカードを選択して使用できる
    • カード選択の入力が正しく受け付けられることを確認する
    • 不正な入力に対して適切なエラーメッセージが表示されることを確認する

ランダム性の検証

  • デッキのシャッフルによるランダム性
    • シャッフル結果が毎回異なることを確認する
    • シャッフルが偏っていないことを統計的に確認する

複数ゲームの連続実行

  • ゲームを再度開始できる
    • ゲーム終了後に新しいゲームを開始できることを確認する
    • 前のゲームの状態が新しいゲームに影響しないことを確認する

パフォーマンスの検証

  • ゲームの処理が遅延なく行われる
    • 各ターンの処理時間が許容範囲内であることを確認する
    • 大量のゲームを連続して行った場合でも性能が劣化しないことを確認する

Claude 3.5Sonnet:

ゲームの基本構造と重要な要素を踏まえつつ、TDDで効率的に進められるようなテストリストを作成します。

プレイヤー対戦TCGのテストリスト

1. ゲームの基本構成要素を最小限で作成

  • 2人のプレイヤーが存在し、それぞれが名前とライフポイント(20)を持つことを確認
    • プレイヤーを作成できる
    • プレイヤーの初期ライフが20である
    • プレイヤー名を取得できる
  • カードの基本構造を実装
    • カードは攻撃力(1-5)を持つ
    • カードの攻撃力を取得できる

2. デッキの基本機能

  • 5枚のカードでデッキを作成できる
    • デッキのカード枚数が5枚である
    • デッキから特定のカードを参照できる
  • デッキのシャッフル機能
    • シャッフル前後でカードの総数が変わらない
    • シャッフル後にカードの順序が変更されている
    • 複数回シャッフルしても正しく動作する

3. 最小限のゲームの進行機能

  • プレイヤーが交互にターンを実行できる
    • 現在のターンプレイヤーを取得できる
    • ターンを次のプレイヤーに渡せる
  • 基本的なカードプレイの流れ
    • プレイヤーがカードを使用できる
    • カードの使用により相手のライフが減少する
    • 使用したカードがデッキから除外される

4. 勝利条件の判定

  • ライフポイントによる勝敗判定
    • プレイヤーのライフが0以下になった時点で負けとなる
    • 勝者が正しく判定される
    • 両者のライフが1以上の場合はゲームが継続する

5. エラー処理と例外ケース

  • 不正な操作の防止
    • ターン外のプレイヤーはカードを使用できない
    • 既に使用済みのカードは使用できない
    • 存在しないカードインデックスを指定した場合にエラーとなる

6. ゲーム全体の流れ制御

  • ゲームの開始から終了までの一連の流れ
    • ゲームを正しく初期化できる(プレイヤー作成、デッキ配布、シャッフル)
    • ターンを正しく進行できる
    • 勝敗が決まった時点でゲームが終了する

7. 状態の表示と取得

  • 現在のゲーム状態の確認
    • 各プレイヤーの現在のライフポイントを表示できる
    • 残りのデッキ枚数を確認できる
    • 現在のターンプレイヤーを確認できる

このリストの特徴: 1. 最小限の機能から開始し、徐々に機能を追加する構成 2. デッキのシャッフルという不確実な要素を早めに実装 3. 基本的なゲームの流れを早い段階で確認できる 4. エラーケースは基本機能が動作した後で実装 5. 各項目は具体的な振る舞いを示し、実装の方向性が明確 6. テストの意図が理解しやすいよう、説明的な記述を心がけた

最初に着手すべきテストケース: python def test_create_player(): player = Player("Player1") assert player.name == "Player1" assert player.life == 20

ケント・ベックの講演 "TDD Theme&Variations" Tech Excellence Conference

Tech Excellence Conferenceというオンラインカンファレンスが先日あって、ケント・ベックがTDDをテーマに講演とQ&Aをしました。

www.techexcellence.io

なお他の講演者のものも含め、YouTubeで視聴できます。英語字幕もつくし、ライブ視聴者のコメントも見られて楽しいです。

youtube.com

ケント・ベックの話を聞きながら、自分が気になったところをメモしました。聞き逃し、聞き間違いがありますし、自分自身の興味関心に偏り、自分の解釈も混じっています。興味を引かれたら、ぜひ動画を見てみてください。

  • 10歳の頃の話 テープでプログラムを読み込み、期待する結果もテープで読ませて、比較するプログラムを読ませた
  • Smalltalk was personal programming environment
  • バカなことを思いついて、コストが小さいなら、やってみろ。コストが小さくて誰もやったことがないことが実はバカじゃなかったらいいよね
  • 1997年JUnitをErich Gammaと書いて、Martin Fowlerに渡したら、めっちゃ流行った
  • TDDの誕生は1995年、JUnitのせいで再発見、注目された
  • TDD本の表紙はカテドラル。ローカルの個別の判断が、全体としては統一された一貫した成果になるというイメージ
  • GOOS本でClassical TDDが終わった
  • Canon TDD。これが唯一のやり方ではない。ここから発展させて自分のものにする。しかし、これとまったく違うものはTDDではない
  • トップダウンかボトムダウンかとよく質問されるが、どちらでもない。既知から未知へ、一歩ずつ進むもの
  • モックについて。モックは一時的な代替品だった。テストに使うなら、モックなしで書けることを考えてみる
    • これはテストの12の側面?要素?を図示したもの。Test Desiderata。Desiderataという言葉はないよ
  • TDDによって得られるであろう効果、影響
  • TDDはワークフローであってテスティング/設計/プログラミング技法ではない、とも言える…… いやいや、TDDはテスティング/設計/プログラミング技法だ。ただ技法を用いても、いい成果が自動的に得られるわけではなくて、よい判断をしないといけない
  • QAは絶対必要。QA部門は絶対不要。

動画はこちらです

www.youtube.com

TDDで生成AIに仕様と設計を指示してみました

生成AIでプログラミングするには、コードを導くプロンプトを書きます。テスト駆動開発 (TDD) ではプロダクトコードを導くテストを書きます。それならば、人がテストを書いてAIにプロダクトコードを書いてもらったらどうだろうか。

そう思って実験してみたところ、思ったよりもスムーズに進み、プロダクトコードはほぼすべて生成AIだけで完成しました。プロダクトコードは、私が書いたテストおよび最終的な仕様を満たしています。あくまで所感ですが、以下のような効果がありました。

  • 仕様を満たすプロダクトコードが、短時間で完成した
  • 私が考えた設計意図を、テストを通して実装に繋げられた
  • コードの詳細な理解は、自分で書いたときよりは劣る
  • テストとしての網羅性は不完全。普通のTDDと同程度で、テストが特に多く必要とはならない

テストの網羅性が不完全というのは、網羅的なテストを書かなくても妥当なプロダクトコードができるという意味で、ここではメリットとして取り上げています。

TDDはテストを先に書く (テストファースト) というよりは、テストコードとプロダクトコードを同時に、並行して少しずつ書き足していくアプローチです。小さなテストをひとつ書き、プロダクトコードを少しだけ書き進める。今回の実験でも小さいサイクルで意識して、人間プログラマがテストをひとつ書き、生成AIにプロダクトコードを少し書いてもらうという繰り返しを実践しています。

やってみるなかで、AIを利用したTDDの上手いやり方や注意点もいくつか発見しました。

  • 人が仕様を元にテストを書いてAIにプロダクトコードを生成してもらうと良い
  • 内部設計についてのテストを書いて、設計意図を伝える
  • 生成結果をクリアにイメージできるようにテストを書く。生成結果がイメージと合っているか確認する
  • 生成されたコードが不十分なら、問題を指摘するテストを書く
  • 生成されたコードが理解できなくなったら、後退してからテストと設計を見直す
  • テストが失敗したらチャットでAIに直してもらう。失敗時の実行結果に加えて、問題や対応方針を読み取って伝える
  • テストの整理もAIに頼める。テストの構成がはっきりしていれば、テストの生成も部分的に頼める

今回の実験にあたり、クリエーションライン株式会社からAnthropicのAPIキーを提供していただきました。感謝いたします。なお私 (やっとむ)は、クリエーションライン株式会社をアジャイルコーチとして支援しています (2024年現在)。

お題はLeetCodeのものを改変した、独自のプログラミング課題を用いています。IDECursor、AIモデルはclaude-3.5-sonnet、言語はPythonとpytest、人間プログラマは私です。実験の様子はステップバイステップで記録し、どのようにテストとプロダクトコードを書き進めたか把握できるようにしています。また、生成AI対応IDEであるCursorとClaude3.5 Sonnetモデルの使い方の、説明にもなっていると思います。

資料は長くなってしまったので、Google Documentで読めるようにしました。以下から閲覧できます。

TDD&AIで仕様通りのテストとコードを書いていく - Google ドキュメント




以上の内容はhttps://yattom.hatenablog.com/より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14