LoginSignup
22
23

More than 5 years have passed since last update.

C++で簡易単体テスト。assert、静的解析

Last updated at Posted at 2016-03-15

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

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ですね

static_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

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は見やすいし便利だったので、なんとかして動くようにしたいですね・・

22
23
0

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
22
23