閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

CppSpec - C++でもRSpecみたいなスペックを書きたい

C++でBDDをやろうというもの、らしい。サンプルを見る分にxUnitのassert_*系の関数名をBDDっぽいものにしたような感じなのかな。ちょっと気になるのだけどビルドするのにBoost.Filesystemだとか必要なようでビルドに時間がかかりそうなので使ってはいない。ただ、これを見て少し思ったことがあるので書いてみる。

CleanCodeで指摘されていたのだけれど、assert_equals(expected, actual)のような関数は、引数の順番を間違えやすいという記述があって、確かに久しぶりにテストを書こうとすると毎回忘れている気がする。これを、RubyRSpecでは以下のように書けるので、引数を間違えることがなくなる。

describe "Add" do
  it "1+1=2" do
    (1+1).should == 2
  end
end

これを見て、C++でも、たとえば C++ テンプレートテクニックなどで紹介されるような拡張メソッドを利用して、 (1+1) | should(2) みたいに書けると間違えづらくなるのかなぁと思いました。

// spec.h
#ifndef _SPEC_H_
#define _SPEC_H_

#include <assert.h>

template<class T>
struct should_t {
  should_t(T const& actual) : actual(actual) {}

  bool operator()(T const& expected) {
    return expected == actual;
  }

private:
  T const& actual;
};

template<class T>
should_t<T> should(T const& actual)
{
  return should_t<T>(actual);
}

template<class F>
void operator|(int const& expected, F f)
{
  assert(f(expected));
}
#endif
// hoge.cpp
#include "spec.h"
int main()
{
  (1+1)|should(2);
}

CppSpecは specify という関数がやはり複数の引数を取るので、これを引数ひとつだけにできるといいのになぁと。サンプルの stackIsEmpty とかは、うまく単一引数に押さえてて、この辺はうまいのかなと思いましたが。

Clean Code アジャイルソフトウェア達人の技

Clean Code アジャイルソフトウェア達人の技


C++テンプレートテクニック

C++テンプレートテクニック