プログラムを作ったあとに、バグが見つかって大変だった経験、ありませんか?修正しようとしたら、別の場所が壊れちゃって、さらに大変に。そういうことを防ぐ方法が「テスト駆動」なんだ。この記事を読めば、テスト駆動がどんなやり方で、なぜそんなにプログラマーに大事にされているのか、きっとわかるよ。
- テスト駆動は プログラムを作る前にテストを先に書く という開発の方法です
- バグが減ったり安全に修正できたり など、たくさんのメリットがあります
- テスト→実装→リファクタリング というサイクルを何度も繰り返すんですよ
もうちょっと詳しく
テスト駆動は「Red→Green→Refactor」という3ステップを繰り返すやり方です。最初にテストを書くと、当然プログラムがまだできていないからテストは失敗します(Red)。そこで、そのテストに合わせてプログラムを書いて、テストが成功するようにします(Green)。それができたら、コードを整理したり改善したりします(Refactor)。この3ステップを何度も繰り返して、プログラムを完成させていくんだ。
テストが「赤」から「緑」になる感じで、目に見える進捗が感じられるのが楽しいんだ。
⚠️ よくある勘違い
→ 実は逆。テスト駆動を使うと、最終的には修正にかかる時間が減ってスピードアップするんだ。短期的には時間がかかるように見えるけど、長期的には得をするんですよ。
→ その通り。修正が必要になったときに、テストがあれば安心して直せるから、結果的に早く完成するんだ。
[toc]
テスト駆動とは何か
テスト駆動は、つまり「テストを書いてからプログラムを書く」という、ちょっと変わった開発のやり方なんだ。普通、私たちはプログラムを作って、その後で「ちゃんと動くかな?」と確認しますよね。でもテスト駆動では、その順番が逆になるんだ。
想像してみてください。スマートフォンのゲームアプリを作るとしましょう。「プレイヤーがボタンを押したら、キャラクターが右に5ピクセル移動する」という機能を追加したいとします。普通のやり方なら、そのコードを書いて、「あ、右に5ピクセル移動しました。よし、完成」となりますね。
でもテスト駆動なら、その前に「ボタンを押したら、キャラクターが右に5ピクセル移動するはず」というテストを書くんだ。当然、プログラムがまだできていないから、そのテストは失敗します。それから、そのテストを成功させるために、プログラムを書くんですよ。
なぜそんなことをするのか。それはね、テストを書くことで「何をプログラムしたらいいのか」がはっきりするからなんだ。テストを見れば、「あ、このプログラムはこういう動きをするべきなんだ」ということが誰でもわかるようになるんですよ。これがテスト駆動の核心なんだ。
もう一つ大事なポイントは、テスト駆動を使うと、プログラムが「どうするべきか」という仕様(つまり、プログラムの説明書)をテストの形で残すことができるってことなんだ。後で誰かがそのプログラムを読むときに、テストを見れば「あ、このプログラムはこんなことをするんだ」ってすぐにわかるんですよ。説明書を別に書く手間がかからない。テスト自体が説明書になっているんだ。
テスト駆動は、ちょっと難しそうに聞こえるかもしれませんが、慣れるとすごく楽になる方法なんだ。プログラムの品質が上がって、バグが少なくなって、修正も簡単になるんですよ。なぜそうなるのかは、これからお話しする内容を読めばわかるよ。
テスト駆動はいつ生まれた?
テスト駆動という考え方は、2000年代初めにアメリカのプログラマーたちが考えた方法なんだ。当時、大きなプログラムを作ると、バグがたくさん出てきて、修正するのに何ヶ月もかかってしまうという問題がありました。それを解決するために、「テストを先に書く」という方法が生まれたんですよ。
Red→Green→Refactorのサイクル
テスト駆動の基本は、3つのステップを何度も繰り返すこと。このステップを「Red→Green→Refactor」って呼ぶんだ。言葉ではちょっと難しそうに聞こえるけど、実はすごく簡単なんですよ。
「Red」というのは、テストが失敗している状態をあらわす赤い信号みたいなものなんだ。あなたが「このプログラムはこういう動きをするはず」というテストを書くと、プログラムがまだできていないから、テストは失敗します。テスト画面に大きく「FAIL」とか「赤い×」が表示される。それが「Red」なんですよ。
「Green」というのは、テストが成功している状態。プログラムがテストの期待通りに動いて、「PASS」とか「緑の○」が表示される。これを見ると、「あ、このプログラムはちゃんと動いた」ってわかるんだ。すごく気持ちいい瞬間ですよ。
「Refactor」というのは、つまり「コードを整理する」という意味なんだ。テストが緑になって、プログラムが動くようになったら、そのプログラムをもっと読みやすくしたり、効率的にしたりする作業をするんですよ。
ステップ1:Red(テストが失敗)
まず、プログラムが何をすべきかを考えます。例えば「電卓アプリで、2+3を計算すると5が返ってくるはず」という要求があったとしましょう。そうしたら、その要求に合わせてテストを書くんだ。
「add(2, 3)という関数を呼んだら、5が返ってくるはず」というテストコードを書きます。でも、プログラマーはまだ add という関数を作っていないんだ。だから、テストを実行すると、「この関数なんか知りません」と言われて失敗します。これが Red なんですよ。
ステップ2:Green(テストが成功)
次に、そのテストを成功させるようなプログラムを書くんだ。「add(2, 3)が呼ばれたら、2と3を足して5を返す」という関数を書きます。シンプルなプログラムでいいんだ。凝った書き方は必要ありません。とにかく、テストを成功させることだけを考えるんですよ。
プログラムを書いたら、もう一度テストを実行します。すると「テスト成功!」という表示が出ます。画面が赤から緑に変わる。それが Green なんだ。この瞬間、プログラマーは「よし、ちゃんと動いた」って実感できるんですよ。
ステップ3:Refactor(コードを整理)
テストが成功したら、そのプログラムをもっと良くする作業をするんだ。例えば、変数の名前を「わかりやすい名前」に変えたり、同じようなコードを簡潔にまとめたり、コメントを足したりするんですよ。
大事なのは、テストが緑のままでいることなんだ。テストが成功している状態を保ちながら、プログラムを整理する。もしプログラムを修正して、またテストが失敗してしまったら、修正前に戻すんですよ。テストが成功するまで頑張ります。
このステップが終わったら、また新しい機能をテストから書き始める。「3+4=7になるはず」というテストを書いて、また Red→Green→Refactor のサイクルを回す。これを何度も何度も繰り返して、プログラムを完成させていくんだ。
テスト駆動を使うメリット
なぜテスト駆動が大事なのか。それは、テスト駆動を使うと、プログラム開発がすごく楽になるからなんだ。具体的には、どんなメリットがあるのか、一つ一つ見ていきましょう。
メリット1:バグが少なくなる
テスト駆動の最大のメリットは、つまりバグが減るということなんだ。なぜか。テストを先に書くということは、その時点で「プログラムがどう動くべきか」をはっきりさせているからなんですよ。
普通のやり方だと、プログラマーが「こんな感じかな」と思いながらコードを書きます。その後、誰かがテストをして「あ、この部分がバグってた」と発見する。修正して、また別のバグが見つかる。この繰り返しなんだ。
でもテスト駆動なら、最初からテストに合わせてプログラムを書いているから、書き終わった時点で「このテストに合うプログラムができた」という確信がある。バグを見逃す可能性がぐっと減るんですよ。
メリット2:修正が安心
プログラムを使っていて、「あ、ここをこう改善したい」と思うことがありますよね。でも、改善すると別の場所が壊れちゃうんじゃないか、という不安がある。だから、なかなか修正に手を出せない。
テスト駆動を使っていると、テストがたくさんあるんだ。プログラムを修正して、テストを実行する。もし修正で他の機能が壊れていたら、テストがすぐに教えてくれる。「あ、この修正で、あそこのテストが失敗しちゃった」ってわかるんですよ。だから、安心して修正できるんだ。
テストがない場合、修正した後も、本当に大丈夫なのか、何度も何度も手動で動作確認しないといけません。すごく時間がかかるんだ。でもテストがあれば、ボタン一つでテストが自動で実行される。「テスト成功。大丈夫」って一瞬でわかるんですよ。
メリット3:設計が自然と良くなる
テストを先に書くと、プログラムの設計(つまり、プログラムの組み立て方)が自然と良くなるんだ。なぜか。テストを書くには、その関数が「どんな入力をもらって、どんな出力をするのか」をはっきり決めないといけないからなんですよ。
そうしていると、プログラマーは「あ、この関数は一つの仕事だけをする方が、テストしやすいな」とか「この部分は別の関数に分けた方が、テスト書きやすいな」って気がつくんだ。自然と、良い設計になっていくんですよ。
プログラムは、たくさんの小さな関数(つまり、小さな命令のセット)が協力して動いています。テスト駆動を使うと、その関数一つ一つが「やることがはっきりしていて、テストしやすくて、他の関数と独立している」という、すごく良い状態になるんだ。
メリット4:ドキュメントの手間が減る
普通のプログラム開発だと、コードの他に「このプログラムはこんなことをします」という説明書(ドキュメント)を書かないといけません。でもテスト駆動を使うと、テスト自体が説明書になるんだ。後から誰かがコードを読むときに、テストを見れば「あ、この関数はこんなことをするんだ」ってすぐにわかるんですよ。
テスト駆動の実例
ここまで、テスト駆動の基本とメリットを説明してきました。でも「実際にはどんな感じなんだろう」と思いますよね。簡単な例を使って、テスト駆動がどんなプロセスなのか、実際に見てみましょう。
例:買い物カゴの合計金額を計算する関数
あなたが、オンラインストアの「買い物カゴの合計金額を計算する」という機能を作るとしましょう。テスト駆動で、どうやって作るか、ステップバイステップで説明しますね。
ステップ1:テストを書く(Red)
まず、テストを書きます。「商品A(500円)と商品B(300円)が買い物カゴに入っているとき、合計金額は800円になるはず」というテストを書くんだ。
テストのコードは、こんな感じですね:
def test_cart_total():
cart = [500, 300]
result = calculate_total(cart)
assert result == 800
でも、プログラマーはまだ calculate_total という関数を作っていないから、このテストを実行すると「そんな関数ないよ」と言われて失敗します。Red ですね。
ステップ2:プログラムを書く(Green)
次に、そのテストを成功させるプログラムを書きます。シンプルでいいんだ。「買い物カゴの中の全ての金額を足して返す」というプログラムを書く。
def calculate_total(cart):
return sum(cart)
これだけです。すごくシンプル。テストを実行すると、「テスト成功!」と表示される。Green になりました。
ステップ3:コードを整理する(Refactor)
今のコードはシンプルすぎて、整理することがないかもしれませんね。でも、もし商品の消費税を考える必要があったら、コードをちょっと修正します。でも、修正した後も、テストが成功していることを確認するんだ。テストが成功している状態を保つ。
ステップ4:次の機能をテストから書く
次に「割引クーポンがある場合、割引を適用した金額が計算されるはず」というテストを書く。また Red になります。そして、そのテストを成功させるプログラムを書く。Green になります。
こんな感じで、テストを書く→プログラムを書く→コードを整理する、というサイクルを何度も何度も繰り返して、プログラムを完成させていくんだ。最終的には、たくさんのテストと、それに合わせた堅牢なプログラムが完成するんですよ。
テスト駆動で気をつけること
テスト駆動は素晴らしい方法なんだけど、気をつけることもあるんだ。まず、テストが完璧である必要はないということ。テストを完璧に書こうと思うと、時間がかかってしまいます。「今のところ、このテストでいいや」という感じで、シンプルなテストから始めるんですよ。
それからね、テストを書くのに時間がかかるということも認識しておくべき。テスト駆動を使うと、プログラムを書く時間と同じくらい、テストを書く時間がかかるかもしれません。でも、その時間は無駄じゃない。後で修正するときの時間が大幅に減るんだ。
テスト駆動を始めてみよう
ここまで読んで「あ、テスト駆動、ちょっとやってみたいな」って思った人もいるかもしれませんね。テスト駆動を始めるのは、そんなに難しくないんだ。ちょっとのコツを知っていれば、誰でも始められるんですよ。
ステップ1:小さい機能から始める
テスト駆動を始めるなら、まずは小さい機能から始めるんだ。「100行のプログラムを作る」とか「3つの関数を実装する」くらいの、小さいスケールでいいんですよ。大きな機能から始めると、テストを書くのが大変になってしまいます。
ステップ2:テスト用の道具を用意する
テスト駆動を使うには、テストを簡単に書き、実行できるツールが必要なんだ。プログラミングの言語ごとに、テスト用のツール(つまりテストフレームワーク)があります。Pythonなら「pytest」、JavaScriptなら「Jest」、Javaなら「JUnit」というツールが有名ですね。
これらのツールを使うと、テストを書いて、実行するのがとても簡単になるんだ。最初は、そのツールの基本的な使い方を学んでから、テストを書き始めるといいですよ。
ステップ3:テストを書く習慣をつける
テスト駆動を続けるコツは、とにかく習慣にするということなんだ。最初は、プログラムを書く前にテストを書くのが難しく感じるかもしれません。でも、何度か繰り返していると、慣れてくるんですよ。
毎日、小さなテストを書く。テストを成功させるプログラムを書く。これを習慣にしていると、いつの間にか「あ、テスト駆動、楽だな」って思うようになるんだ。
ステップ4:チームで使う
テスト駆動は、一人で使うのも良いですが、チーム(つまり、複数の人で一緒にプログラムを作る場合)で使うと、さらに力を発揮するんだ。チームでテスト駆動を使うと、みんなが書いたプログラムを修正するときに、テストがあるから安心できるんですよ。
誰かがプログラムを修正して、別の人が「あ、この修正で私が書いた部分が壊れちゃった」って気がつく必要がない。テストがあれば、自動的に「壊れてますよ」って教えてくれるんだ。
よくある質問への答え
Q:テスト駆動は、初心者でも使える?
A:もちろん。むしろ初心者だからこそ、テスト駆動を使う方がいいんだ。テストを見れば「このプログラムは何をするべきか」がはっきりするから、プログラムの書き方を学ぶのに役立つんですよ。
Q:テストを書くのが得意じゃなくても大丈夫?
A:大丈夫。テストは、プログラムと同じで、何度も書いていると上達するんだ。最初は簡単なテストから始めて、少しずつ複雑なテストを書いていけばいいんですよ。
Q:テスト駆動は、どんなプログラムでも使える?
A:ほぼ全てのプログラムに使えるんだ。ただ、見た目を作るプログラム(UIとか画像処理)は、テストが書きにくい場合があります。でも、その場合でも、工夫すれば何とか使えるんですよ。
