#単体テスト書いてますか?
C++では一度も単体テスト書いたことありません・・・申し訳ございません・・
反省しこれから 単体テストをちゃんと作ろうと思います
理想形は Jenkinsおじさんをこき使って Gitと連携です
C++には boost.testやCppTest、GoogleTest等があります
ただし、Jenkinsの設定が面倒だったり、クライアントサーバ型の場合はモックも作る必要が出るので
今回は 超お手軽にテストができる
assert、static_assert を使うことに! お手軽!!
##assert
assert(exp)
プログラム実行時に、引数の条件式が trueの時は何も行わない
falseの場合は、 ファイル名、行番号、関数名等をprintoutし プログラムを終了します
ただし #define NDEBUG が定義されている場合は、この部分はコンパイル対象にならないので
リリース時は makefileに -DNDEBUGを定義しましょう!
#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ですね
#include<assert.h>
#include<iostream>
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は見やすいし便利だったので、なんとかして動くようにしたいですね・・