LoginSignup
9
13

More than 5 years have passed since last update.

Catch というマクロライブラリで C++ のコードをテストする

Last updated at Posted at 2015-05-12

概略

C++ のコードをテストする道具として、Catch というかんたんツールを見つけたので使ってみた。

背景

近年()、ハードウェア性能の急速な退化などの要因で、私が新しくプログラムを書くときの選択肢として、C, C++ が少しずつではあるが再登場してきた。
というか、普通に JavaScript とかより抽象度が高いし、シー言語たのしいいい。

ところで、私は C, C++ 用のものを含め、ユニットテストのふれーむわーくなるものを使いこなせたためしがない。主な理由は2つあって:

  1. 重厚長大かつ意味不明: なんで assert( f(v) == v' ) を確かめるためだけに、どっかの知らんやつが考えたさいきょうのお作法を何時間も解読しなきゃいけねーんだよ。
  2. そもそも f(v) == v' 的なものは、だいたい自明に実装する。本当にテストしたいことの8割方は、ループの不変条件とか、「UIのボタンが絶対に迷子にならない不変条件」とかだ。

Catch

Catch は、C, C++ のテストツールだが、特長は、上述のような頑固な static おじさんでも10分で使える簡潔さにある。

使い方は、

  1. ヘッダファイルを1つだけ #include して、
  2. そこで定義されたそれっぽいマクロでテストケースを書いて、
  3. コンパイルして
  4. 出てきたバイナリを実行

これだけ。具体例を、公式のチュートリアル から適切な範囲で引用() してみよう:

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"

unsigned int Factorial( unsigned int number ) {
    return number <= 1 ? number : Factorial(number-1)*number;
}

TEST_CASE( "Factorials are computed", "[factorial]" ) {
    REQUIRE( Factorial(1) == 1 );
    REQUIRE( Factorial(2) == 2 );
    REQUIRE( Factorial(3) == 6 );
    REQUIRE( Factorial(10) == 3628800 );
}

例題はありがちな fib で、簡単のためにテストしたい実装を同じソースに埋め込んでいる。もちろん、ふだん使うときは実装は別のソースにわけてリンクする、というかもういっそ #include "oreore-code.cpp" でもいいんじゃないかな...

これをコンパイルして実行すると、こんな感じ:
image

試してないが、CI1 用の出力を出したり、びへいびやーどりぶん的な書き方もできるらしい2

まとめ

手早くすませることが求められて、それが実現可能ならば、そのようにしましょう。

補足

Q. private メソッドのテストはどうすんの?
A. #define private public しろ。
公式の issue に本当にそう書いてある

やめとけ。この話終わり!close されていたのでお詫びして訂正いたします。

--


  1. 余談だが、このギョーカイで 「Integration」 という言葉が何を意味しているのか、さっぱり理解できていない。 

  2. 余談だが、いつから BDD という略語が「二分決定図」以外のものを指すようになったんだ? 

9
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
13