特集

「テスト駆動開発」はプログラマのストレスを軽減するか?

株式会社ピーデー
川俣 晶
2003/11/08

Page1 Page2 Page3 Page4

レッド/グリーン/リファクタリングの三拍子

 レッド/グリーン/リファクタリングというのは、それぞれ特に新しい用語というわけではない。レッドとグリーンは、それぞれ、NUnitのようなテスト・ツールで表示される結果を意味する。これらのツールでは、テストが進行するにつれてバーが伸びていくように表示することが多いのだが、その際、エラーがなければ緑色(グリーン)、エラーが起きると赤色(レッド)になる。つまり、レッドとはテストがパスしない状況、グリーンとはテストをパスしている状況を意味する。リファクタリングはすでに説明したが、ソース・コードをきれいな形に修正する作業である。

.NET用テスト・ツール「NUnit」が表示するバー
エラーがなければ緑色(グリーン)、エラーが起きると赤色(レッド)のバーが、テストが進行するにつれて伸びていく。

 これらを踏まえてレッド/グリーン/リファクタリングという言葉を解釈し直せば、

テスト失敗/テスト成功/コードをきれいにする

と読み替えることができる。とはいえ、

レッド/グリーン/リファクタリング

といった方が格好よいし、リズム感もあるので、こちらの言葉を使っていくことにしよう。

 さて、ここでは足し算を行うメソッドを開発する例で、簡単にその手順を見てみよう。まったく実用性はないが、そこは説明のためのサンプルだと思ってお付き合いいただきたい。プログラム言語にはC#を、テスト・ツールにはNUnitを使うことを前提に話を進めよう。

■テストが失敗する段階:レッド

 レッドはテストが失敗する段階である。まず、ここからTDDのサイクルはスタートする。当然のことながら、「テストが失敗する」というのは、「何もできていない」こととイコールではない。「テストが失敗する」ためには、テストが作成されていて、しかも実行可能でなければならない。それは、作業手順が正しく進ちょくしていることの証明になる。作業が進行していなければ、レッドにすら達していない状況もあり得るわけである。

 さて、足し算を行うメソッドのためのテストを作成しなければならない。まずは、シンプルに、「1+2=3」という計算を試すテストを書いてみた。

using System;
using Sample;
using NUnit.Framework;

namespace TestSampleClass
{
  [TestFixture]
  public class TestSampleClass
  {
    [Test]
    public void Plus()
    {
      Assertion.AssertEquals( 3, SampleClass.Plus(1,2) );
    }
  }
}
「1+2=3」という計算を試すテスト

 Assertion.AssertEqualsメソッドの第1引数は、期待される値。第2引数は実際の値を指定している。もし、この2つが一致すればグリーンのバーが、一致しなければレッドのバーが見えることになる。

 さて、これだけではまだレッドの段階にも達することができない。テスト対象となるコードをまだ記述しておらず、これだけではビルドできないからである。ビルドするために、最低限のコードを書き込んでみよう。

using System;

namespace Sample
{
  public class SampleClass
  {
    public static int Plus( int x, int y )
    {
      return 0;
    }
  }
}
テスト対象となる最低限のコードを書き込んだ足し算メソッド

 これでビルドして実行することが可能になった。NUnitで実行してみると、以下のようにレッドの状態になった。

レッドの状態になったNUnitの実行画面
ビルドするための最低限のコードしか書き込んでいないためテストは失敗する。レッドを解消することが現時点での目標となる。

 これでレッドは完了である。通常、この段階に達するまでに必要とされる時間はほんのわずかである。もしかしたら、この程度のテストではメソッドの完全性を保証することはできない、と悩む読者がいるかもしれないが、ここでは悩まないことにしよう。一度に1つのことだけを考えて解決していくのが、TDD的な態度である。すでに、われわれは1つのレッドを手に入れた。このレッドを解消することが現時点での目標となる。ほかのテストケースを付け足して、レッドの項目の数を増やすべきではない。レッドは一度に1つとすべきなのである。

 では、次の手順に進もう。

■テストが成功する段階:グリーン

 次は、テストをパスさせ、グリーンのバーを見る段階である。ただし、ここで完全なプログラムを書き込もうとしてはいけない。より正確にいえば、どのように記述すればよいか分かっている場合は、それを書き込んでしまうという方法もある。これは、「明白な実装」と呼ばれるものである。通常の開発では、分かり切ったコードを書き込む場合は、いきなり明白な実装を行う場合も多いだろう。しかし、ここではTDDの手順を説明するために、あえて明白な実装は行わずに進めてみよう。

 さて、グリーンの段階で行うべきことは、どれほど汚い手段を使っても、最短の時間でグリーンのバーを見ることである。そう、ここでは汚いコーディングが許されるのである。通常のプログラム開発では、良識あるきれいなコードを書くことが求められる。もちろん、TDDであっても、最終的に目指すのは良識あるきれいなコードである。しかし、ほんの短い時間であれば、汚いコードがあってもよい、とTDDでは考える。グリーンの段階の次に、リファクタリングという段階があり、そこで汚いコードは姿を消すのである。あくまで、リファクタリングまでの期間に限って汚いコードは許される。

 では、最も安直で直接的な手段で、グリーンのバーを見ることにしよう。足し算メソッドを以下のように書き換えてみた。

public static int Plus( int x, int y )
{
  return 1+2;
}
最も安直で直接的な手段で書き換えた足し算メソッド

 これを実行すると、見事グリーンのバーを見ることができた。

グリーンの状態になったNUnitの実行画面
足し算メソッドは必ず3を返すためテストは成功する。

 これでグリーンの段階は終了である。

 ここで、ちょっと待て、と思った人もいるだろう。このメソッドは実際には引数の値と関係なく、必ず3という数字を返す。これが役に立つはずがない。もちろん、それは分かっている。なぜ、役に立たないメソッドを使ったかといえば、TDDの「三角測量」というテクニックで、これを解消していく手順を次に見せるためである。


 INDEX
  [特集]「テスト駆動開発」はプログラマのストレスを軽減するか?
     1.新しいソフトウェア開発技法へチャレンジできるか?
   2.レッド/グリーン/リファクタリングの三拍子
     3.再びレッドとグリーン、そしてリファクタリング
     4.どんなときにテスト駆動開発を採用すべきか
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間