More than 1 year has passed since last update.

単体テスト書いてますか?

C++では一度も単体テスト書いたことありません・・・申し訳ございません・・
反省しこれから 単体テストをちゃんと作ろうと思います

理想形は Jenkinsおじさんをこき使って Gitと連携です
C++には boost.testやCppTest、GoogleTest等があります

ただし、Jenkinsの設定が面倒だったり、クライアントサーバ型の場合はモックも作る必要が出るので
今回は 超お手軽にテストができる
assert、static_assert を使うことに! お手軽!!

assert

assert(exp)
プログラム実行時に、引数の条件式が trueの時は何も行わない
falseの場合は、 ファイル名、行番号、関数名等をprintoutし プログラムを終了します

ただし #define NDEBUG が定義されている場合は、この部分はコンパイル対象にならないので
リリース時は makefileに -DNDEBUGを定義しましょう!

assert
#include<assert.h>
#include<iostream>

int main(){    
    int hoge = 4;
    int hoge2 = 5;

    std::cout << "check hog2" << std::endl;
    assert(hoge==4);
    std::cout << "check hoge2" << std::endl;
    assert(hoge2==4);
    std::cout << "fin" << std::endl;

    return 1;
}



結果

check hog2
check hoge2
prog.exe: prog.cc:11: int main(): Assertion `hoge2==4' failed.
Aborted

assert(hoge2==4);
で Abortし finが表示されてませんね。

ちなみに #include 以前に #define NDEBUG を書くと
assert無視され finまで到達します

例えば関数の入力値の範囲チェックや、配列数等のチェックを
リリースビルド時には無視されるので 好きなだけ追加しましょう!

static_assert

static_assert(exp,msg);

コンパイル時に 条件式expを評価し、falseの場合はmsgを表示しコンパイルエラーを吐きコンパイルを中断する

コンパイル時assertですね
```cpp:static_assert

include

include

int main(){

const int hoge = 4;
const int hoge2 = 5;

std::cout << "check hog2" << std::endl;
static_assert(hoge==4, "error");
std::cout << "check hoge2" << std::endl;
static_assert(hoge2==4, "error" );
std::cout << "fin" << std::endl;

return 1;

}

結果

prog.cc: In function 'int main()':
prog.cc:11:5: error: static assertion failed: error
static_assert(hoge2==4, "error" );
^~~~~~~~~~~~~
```

コンパイル時にエラーが出ました
使う場所が限定されますが、コンパイル時にわかる不具合はここで潰すと良いと思います

一例でいうと
・intやfloatの大きさのチェック
・バイトオーダーのチェック
・キャスト時の継承関係チェック

など。
今回私は バイトオーダーチェックなどに使っています

assert、static_assertを使うと、単体テストフレームワークを使うより
簡単にテストが行えますね

静的解析&lint使ってますか??

C++では、メモリリーク、2重開放など色々な不具合が発生するけど
それをコンパイル時に見つけるのが 静的解析ツールで
思った以上に 見つけてくれるので使いましょう

cppcheck、splint、scan-build
等あります。

コンパイラをclangにしている場合は、デフォルトでscan-buildが使えるので
時々実行してみましょう

静的解析ツールは、誤認識率も多少あるので、できれば沢山使うといいと思ってます

scan-build (clang)

clangに最初からついているので scan-buildが便利です!

$ scan-build make -B
とすると、プロジェクト全体の静的解析を行ってくれます
scan-viewで レポートファイルを開けば、問題点をGUIで表示できるので
とても便利です

以前は scan-build make で、プロジェクトの全ファイルの静的解析が出来ていたのですが
なぜか今行なうと ちゃんと動かなくなっており
1ファイルずつ解析しか出来なく・・・
なぜだろう・・・

cppcheck

パッケージあるいはソースからビルドして
cppcheck --enable=all ファイル名
あるいは
cppcheck --enable=all folder フォルダ名
で、チェック結果をコンソールに出力します

enableを指定しないと何も出力されません
チェックしたい項目のみ指定すると便利です

folderは再帰的に呼んでくれるので便利です
特定ファイルの除外、特定ファイルの追加等の柔軟な設定も可能です

splint

http://www.splint.org/faq.html#quest5

Does Splint handle C++?

No, Splint does not check C++ code. We don't have the resources (or the >research justification) to build a C++ front end, but if you are interested in >building a C++ front end the source code is available, and I will certainly be >willing to help.

ということで、C++には対応してないっぽいので ザンネン

結果

現在わたしは、単体テストとして
static_assert、assert をメインで使っています
boost.TestやJenkins連携は 今度トライしようと・・

静的解析としては
scan-buildが便利だったのですが、うまくプロジェクトファイルを読み込めなくなり
原因を探っています。。

ので、現在はメインで cppcheckで特定フォルダごとにチェックしています

scan-buildは見やすいし便利だったので、なんとかして動くようにしたいですね・・