テスト駆動開発(TDD)について

eclipse導入手順(Cygwinの場合)

  1. [プロジェクトエクスプローラ] > 新規 > [C++プロジェクトの作成]でプロジェクト作成
    この際に、[実行可能プロジェクト] > [空のプロジェクト]を選択
  2. ソースファイル(RunAllTests?.cpp)を以下のように作成
    #include "CppUTest/CommandLineTestRunner.h"
    
    int main(int argc, char** argv)
    {
        return CommandLineTestRunner::RunAllTests(argc, argv);
    }
  3. インクルードパスの指定
    1. プロジェクトを右クリック > [プロパティ] > [C/C++ビルド]>設定を選択
    2. Cygwin C++ Compilerのインクルードを選択
    3. インクルード・パス(-I)で以下のパスを指定
      /cygdrive/c/xxxx(ここは任意)\CppUTest\include
      (ここで、C:と指定してはいけないことに注意!
       cygwinをeclipseで使おうとするときは、/cygdrive/c/で置き換えなければダメ)&br;
       追記:/cygdrive/cだと、eclipseで includeファイルを認識してくれない。&br;
             その場合は、/cygdrive/c/とC:\を両方登録する。
  1. ライブラリパスの指定
    1. プロジェクトを右クリック > [プロパティ] > [C/C++ビルド]>[設定]を選択
    2. Cygwin C++ Linkerのライブラリーを選択
    3. ライブラリー(-l)で以下を入力
      CppUTest
    4. ライブラリー検索パス(-L)で以下のパスを指定
      /cygdrive/c/xxxx(ここは任意)\CppUTest\lib
      (ここで、C:と指定してはいけないことに注意!
       cygwinをeclipseで使おうとするときは、/cygdrive/c/で置き換えなければダメ)
    5. CppUTestをコンパイルして、libCppUTest.aを作る。
      (大事!これがわからなくて3時間つぶした)
  2. RunAllTests?.cppを実行して成功。わーい。
    OK (0 tests, 0 ran, 0 checks, 0 ignored, 0 filtered out, 2 ms)

CppUTest実践例

  1. テスト関数を作成(DieTest?.cpp)
    #include "CppUTest/TestHarness.h"
    
    #include "Die.h"
    
    TEST_GROUP(Die){
    };
    
    TEST(Die, InitialValueAfterCreationIsValid) {
      Die d;
      CHECK(d.faceValue() >= 1);
      CHECK(d.faceValue() <= 6);
    }
  2. テスト対象関数のヘッダを作成を作成(Die.h)
    #include "Die.h"
    
    Die::Die() {
    
    }
    
    Die::~Die() {
    }
    
    int Die::faceValue() const {
      return 1;
    }
  3. テスト対象関数を作成(Die.cpp)
    #include "Die.h"
    
    Die::Die() {
    
    }
    
    Die::~Die() {
    }
    
    int Die::faceValue() const {
      return 0;
    }
  4. テストを実行
     ../DieTest.cpp:10: error: Failure in TEST(Die, InitialValueAfterCreationIsValid)
     	CHECK(d.faceValue() >= 1) failed
     
     .
     Errors (1 failures, 1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 3 ms)
  5. あれれ、失敗です。一部修正して再度実行
    #include "Die.h"
    
    Die::Die() {
    
    }
    
    Die::~Die() {
    }
    
    int Die::faceValue() const {
      return 1; /**N ここを0から1に修正 */
    }
  6. よかった。成功です。
    .
    OK (1 tests, 1 ran, 2 checks, 0 ignored, 0 filtered out, 1 ms)

CppUTestをC言語で使う方法

  1. テスト対象関数のヘッダを改造(Die.h)
    #ifndef DIE_H_
    #define DIE_H_
    
    int faceValue(void);
    
    #endif /* DIE_H_ */
  2. テスト対象関数を改造(Die.c)
    #include "Die.h"
    
    int faceValue(void) {
      return 1;
    }
  3. テスト関数を作成(DieTest?.cpp)
    #include "CppUTest/TestHarness.h"
    
    extern "C"
    {
    #include "Die.h"
    }
    
    TEST_GROUP(Die){
    };
    
    TEST(Die, InitialValueAfterCreationIsValid) {
      CHECK(faceValue() >= 1);
      CHECK(faceValue() <= 6);
    }
  4. テストを実行!わーい。成功だ!!
    .
    OK (1 tests, 1 ran, 2 checks, 0 ignored, 0 filtered out, 2 ms)

C言語でも、CPPUTestは使えます。 キモはテスト関数を.cppでつくり、ヘッダファイルをextern"C"{}で囲むこと

extern "C"
{
#include "xxx.h"
}

CppUTestの結果をeclipseのJUnitビューで表示する方法

  1. 実行ファイルを作成(*.exe)
  2. コマンドプロンプトから実行。その際に、以下のオプションをつける。
    => cpputest_*.xmlという名前のファイルが作成される。
    > *.exe -ojunit
  1. 選択して右クリック > アプリケーションから開く > その他 > JUnitビューを選択
    => これで、JUnitビューで表示される

ここまでは基本。これから応用。

  1. プロジェクトを右クリック > 実行 > 実行の構成 を選択。
  2. C/C++アプリケーションの参照を選択。さっき作った実行ファイルを選択。
  3. 引数タブを選択し、以下を入力
    => これで、Ctrl + F11のショートカットで.xmlファイルを作成可能
    -ojunit
  4. さらに、ウィンドウ > 設定 > 一般 > エディタ > エディタの関連づけを選択
    .xmlファイルを追加し、エディタのデフォルトを JUnitに設定
    => これで、F3のショートカットで開くことが可能

これであなたも 「レッド」→ 「グリーン」→ 「リファクタリング」

ファイル構成メモ

--+--include
  |
  +--lib
  |
  +--objs
  |
  +--src
  |
  +--tests
  |    |
  |    +---testsrc
  |    |
  |    +---RunAlltests.cpp
  |
  +--mocks