連載
» 2007年09月14日 00時00分 公開

連載 C++開発者のための単体テスト入門:第3回 C++アプリケーションの効率的なテスト手法(NUnit編) (4/4)

[επιστημη(えぴすてーめー),著]
前のページへ 1|2|3|4       

C++ネイティブ・コードのテストの制限

 NUnitは.NETに対応した単体テスト・フレームワークですから、ネイティブ・コードの検証にはいくつかの制限があります。

 int型やlong型などの比較検証は、そのまま「Expect(結果値, EqualTo(期待値))」というコードで検証できますが、例えば文字列では、

String^ expected = gcnew String(期待値);
String^ actual = gcnew String(結果値);
Expect(actual, EqualTo(expected));

のようにSystem::String型に変換するか、もしくは、

Expect(strcmp(結果値,期待値), EqualTo(0));

のような検証コードを書くことになるでしょう。

 そのような例を簡単に示しましょう。以下にCounterクラスよりもやや規模の大きなクラスを用意しました。文字列のトークン分割を行う「tokenizer」クラスです(プロジェクトはVisual C++のスタティック・ライブラリ・プロジェクトで「tokenizer」とし、ファイルは「tokenizer.h」などを作成しました)。

#ifndef TOKENIZER_H__
#define TOKENIZER_H__

#include <string>  // stringクラスの利用
#include <utility> // pairクラスの利用

class tokenizer {
public:
  typedef std::pair<std::string::size_type,std::string::size_type>
    range_type;

  // コンストラクタ:区切り文字の集合をパラメータに与える
  explicit tokenizer(const std::string& delimiter);

  // 与えた文字列のトークン分割を開始する
  void start(const std::string& source);

  // start関数に与えた文字列のトークン分割を最初からやり直す
  void reset();

  // トークンを切り出す。切り出すトークンがなければfalseを返す
  bool next();

  // nextで切り出されたトークンを返す
  std::string token() const;

  // nextで切り出されたトークンの位置と長さを返す
  range_type range() const;

private:
  std::string source_; // 分割対象となる文字列
  std::string delim_;  // 区切り文字の集合
  range_type range_;   // トークンの位置と長さ
};

#endif

tokenizerクラスのヘッダ・ファイル(tokenizer.h)

 tokenizerクラスの実装内容は省略します。詳しく知りたい場合は、次のリンクから本稿の全ソース・コードを含むファイルをダウンロードして参照してください(なお、これをビルドするためには「nunit.framework」アセンブリへの参照設定を削除して追加し直す必要があります)。

 このtokenizerクラスのtoken関数は標準C++ライブラリのstd::string型の文字列を返します。token関数が期待した文字列を返すことを検証するコードは以下のようになります(以下のコードは、Visual C++のCLRクラス・ライブラリ・プロジェクト「tokenizerTest」を追加したうえで、tokenizerTest.cppファイルに実装します)。

[TestFixture]
public ref class tokenizerTest : AssertionHelper {
private:
  tokenizer* t_;
  // std::string型をSystem::String^型に変換する
  static String^ str(const std::string& s)
  {
     return gcnew String(s.c_str());
  }

public:
  [SetUp]    void 前準備() { t_ = new tokenizer(","); }
  [TearDown] void 後始末() { delete t_; }

  [Test] void トークンを1つ切り出す() {
    t_->start("hello,world");
    String^ result = str(t_->next());
    Expect(result, EqualTo("hello"));
  }
  ……省略……
};

tokenizerクラスをテストするソース・ファイル(tokenizerTest.cpp)

 NUnitを使ったC/C++コードのテストではテスト・コードをC++/CLIで記述するわけですが、C++/CLIはクラス名やメソッド名に漢字や仮名を使うことができ、適切なメソッド名を与えることで、“何についてのテストか?”がそのままNUnitテストランナーに表示されます。以下の画面はその例です。

tokenizerTest.dllのすべてのテストが成功した例
クラス名やメソッド名に日本語が使えるため、“何についてのテストか?”が分かりやすい。

■おまけ:ReSharper UnitRun

 最後にJetBrainsのReSharper UnitRunを紹介しておきましょう。

 UnitRunはNUnitによるテストをVS 2005のIDE(=統合開発環境)の中で実行できるアドイン・ツールです。UnitRunをインストールすると、次の画面のようにC#/VBのテスト・コードに小さなマークが打たれ、そこをクリックすることでテストが行えます。

テストを実行するために現れるUnitRunのメニュー
C#/VBのテスト・コードに小さなマークが打たれ、そこをクリックすることでテストが行える。

 ここで実際にテストを実行すると、そのテスト結果はVS 2005 IDE内にウィンドウとして表示されます。このウィンドウは、IDEが持つほかのウィンドウと同様、IDE内にドッキングできます。

テスト結果が表示されるUnitRunのウィンドウ

 また、[ソリューション エクスプローラ]の項目を右クリックすると、コンテキスト・メニューに[Run Unit Tests]や[Debug Unit Tests]が現れます。これを選択することで、ソリューションに含まれるすべてのテストをまとめて実行することができます。


 以上で「連載:C++開発者のための単体テスト入門」は完結です。

「連載 C++開発者のための単体テスト入門」のインデックス

連載 C++開発者のための単体テスト入門

前のページへ 1|2|3|4       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。