テストから先に実装できるようになるにはどうすればいいの?
はい。最近出たo1 proに訊いてみました。長いので折りたたみますね。
o1 proさんの回答
結論として:
TDDやテストファースト開発を身につけるには、小規模で明確なタスクから練習する「コードカタ」やワークショップ形式のトレーニングを行い、テストで仕様を明文化する習慣を体に染み込ませることが効果的だ。また、ペアプロやモブプログラミング、既存コードへのテスト導入など、段階的なアプローチをとることで、徐々にテストを書くことが「自然な流れ」になるよう意識的なトレーニングを重ねていくと良い。
詳細:
-
コードカタや演習問題から始める:
「FizzBuzz」などの極めて単純な問題でテストファーストを練習する。最初は超シンプルなロジックとテストで「テストを書いてから実装を行う」流れそのものに慣れる。
これらの演習を反復することで、テストから書くことへの心理的障壁が下がる。 -
ペア・モブプログラミング:
経験のあるエンジニアと一緒にペアプロでTDDを実践する。隣でテスト書きの流れを見せてもらいながら、自分も習慣を学ぶことで、自分一人でやるより早くコツを掴む。
モブプログラミング(3人以上のチームで1つのマシンを共有しながら進める開発)も有効で、テストファーストの思考プロセスを共有できる。 -
段階的な導入:
いきなり大規模な機能をテストファーストで作るのはハードルが高いので、まずは既存機能の一部だけテストする、バグ修正用の小さな関数からテストを先に書いてみる、など、スモールステップで慣らしていく。 -
テスト設計の基礎学習:
単なる「テストコードの書き方」だけでなく、テスト設計の基本(境界値分析、同値分割、正常系・異常系の考え方)を学ぶことで、「実装前にテストケースを洗い出す」ことが自然にできるようになる。 -
ツール・環境整備:
pytestやunittest、mypyなどを導入した整った環境で開発してみる。補助ツールが整っていると、テストを書いたり実行したりが手軽になるため、最初の敷居を下げる。
コード例:シンプルな演習(FizzBuzz)のTDDテストファースト例(Python)
# コメント:下記はテストファーストでFizzBuzzを実装する際の練習例。
# コメント:最初にテストを書く → テストが失敗 → 必要最小限の実装 → テストパス、のサイクル。
from typing import (
Any,
List,
Dict,
)
import pytest
def fizzbuzz(
number: int,
) -> str:
"""
コメント:実装は後から書くので、ここではダミーで空文字を返しておく(TDD初期段階)
"""
return ""
@pytest.mark.parametrize(
"number,expected",
[
(1, "1"),
(2, "2"),
(3, "Fizz"),
(5, "Buzz"),
(15, "FizzBuzz"),
],
)
def test_fizzbuzz(
number: int,
expected: str,
):
"""
コメント:先にテストを書いて、FizzBuzz仕様を明文化
- 3で割り切れると"Fizz"
- 5で割り切れると"Buzz"
- 3と5両方で割り切れると"FizzBuzz"
- その他は数字文字列
"""
result: str = fizzbuzz(number)
assert result == expected, "FizzBuzzの出力が期待と異なる"
最初に上記テストを書く → テストを実行して失敗させる → fizzbuzz関数内を修正してテストが通るようにする流れを繰り返すことで、「テストで仕様を定義してから実装」というプロセスを自然に習得できる。
こうした簡単なトレーニングを繰り返せば、自然と実務でも「まずテストでゴールを決め、それから実装」という思考にスイッチしやすくなる。
なるほど、良いことを言います。たしかにfizzbuzzのように仕様が完全に決まっている関数でテストファーストができないのでは他でテストから書くというのは難しいでしょう。
ではあとはこの「コード書く→テストを実行して失敗させる→修正する...」繰り返しプロセスをどう学習者に提供するかですね。
ということでやってまいりましたGPT-4oさんのキャンバス。実は使ったことがなかったのですが、これがまた便利というかテストファースト実装の勉強のためにできたんじゃないかと思えるくらいジャストフィット。以下がデモ画像になります。
(そもそもこのデモ、人間はテストから書き始めてないじゃんというツッコミはさておき) 「テストが通りません。どうすればいいですか」とかなり丸投げしても適切に回答していることがわかります。エラーをはっきり伝えられない場合でも (fizzbuzz程度なら) 適切に対応してくれることがわかります。対応が適切どころかほぼネタバレになってしまっていますが、ここはシステムプロンプトなどで対応の領域でしょう。
これ個人的にびっくりしたんですが、適切にmainを書くと (これもエラーぶん投げてGPTに書いてもらいましたが) キャンバスでunittestが実行できるんですね。標準ライブラリの強みが出ています。pytestはだめでした。
キャンバスで実行しなくてもいちいちGPTに「テストを実行して」と投げれば実行結果とそこで見つかったバグを教えてくれます。キャンバスで実行した場合、テストなのにどこでfailしたか現時点ではわからないという状況なのでGPTにお願いするほうが丸いでしょう。
ということで、GPT-4oのキャンバス機能でテストファースト実装の練習ができる、でした。