CUnitについての備忘録

##Cunit

CUnitを使う機会が有ったので、備忘録として記載する。
(なお自サイトにも同様の内容を記載している。)

###CUnit:Cの単体テストツール
CUnitはテストコードにリンクして実行を行う
CUnit URL:http://cunit.sourceforge.net/

###CUnit インストール:
Google検索すると先人の方々がCUnitのインストールについて記載されているためそちらを確認していただく方が良いと考えるが、一応、インストールの方法についてもここで触れておく

(1)Cunitファイルをダウンロード
C Unit Testing Framework:https://sourceforge.net/projects/cunit/files/

CUIの場合
wget wget http://jaist.dl.sourceforge.net/project/cunit/CUnit/2.1-2/CUnit-2.1-2-src.tar.bz2
＃ 2016/12/17 現在 最新版は2.1.3だがconfigureが存在しないため,2.1.2を使用する

(2)ダウンロードファイルの解凍及びinstall
ファイル解凍
$ tar xvf ./CUnit-2.1-2-src.tar.bz2 
解凍フォルダへ移動
$ cd CUnit-2.1-2
makefile作成
$ ./configure
make実行
$ make
install
$ make install

(3)ライブラリパスを設定
.bashrcに以下を追記
export LD_LIBRARY_PATH=/usr/local/lib
.bashrcの設定を反映
$ source ~/.bashrc


###CUnit testコード作成
Sample Code: http://cunit.sourceforge.net/example.html
サンプルコードは上記から取得可能
今回は例として素数の時だけjojoを表示するプログラムをCUnitでテストするコードを記載する

src.c: 素数の時だけjojoを表示するプログラム
src.h: src.cのヘッダファイル
tsrc.c: src.cのテストコード
tsrc.h: tsrc.cのヘッダファイル


```c:src.c
#include <stdio.h>                                                              

int jojo();
void chkPrime(int cnt);
void printJojo();
void printNum();

int jojo(){
  int cnt;

  for(cnt=1; cnt <= 10; cnt++) {
    chkPrime(cnt);
  }

  return 0;
}

void chkPrime(int cnt) {
  if(cnt < 2) {
    printJojo();
    return;
  }
  else if(cnt == 2) {
    printJojo();
    return;
  }

  if((cnt % 2) == 0) {
    printNum(cnt);
    return;
  }

  for(int i=3; i <= (cnt/i); i += 2) {
    if(cnt % i == 0) {
      printNum(cnt);
      return;
    }   
  }
  printJojo();

  return;
}

void printJojo() {
  printf("jojo\n");
  return;
}

void printNum(int cnt) {
  printf("%d\n", cnt);
  return;
}
```

```c:src.h
#ifndef _SRC_H_
#define _SRC_H_

int jojo();
void chkPrime(int cnt);
void printJojo();
void printNum();

#endif /* _SRC_H_ */
```

```c:tsrc.c
#include "CUnit/CUnit.h"                                                        
#include "CUnit/Console.h"

#include "tsrc.h"
#include "src.h"

int main() {
  CU_pSuite testSuite;

  /* CUnit初期化 */
  CU_initialize_registry();
  /* Suite登録 */
  testSuite = CU_add_suite("JojoTestSuite", NULL, NULL);

  /* Test関数 */
  CU_add_test(testSuite, "JojoTest", test_jojo);
  CU_add_test(testSuite, "ChkPrimeTest", test_ChkPrime);
  CU_add_test(testSuite, "PrintJojoTest", test_printJojo);
  CU_add_test(testSuite, "PrintNumTest", test_printNum);

  /* CUnit 実行 */
  CU_console_run_tests();
  /* CUnit 終了処理 */
  CU_cleanup_registry();

  return 0;
}

void test_jojo() {

  CU_ASSERT(jojo()==0);

  return;
}

void test_ChkPrime() {

  chkPrime(0);
  chkPrime(2);
  chkPrime(3);
  chkPrime(4);
  chkPrime(10);

  return;
}

void test_printJojo() {

  printJojo();

  return;
}

void test_printNum() {

  printNum(1);

  return;
} 
```

```c:tsrc.h
#ifndef _TSRC_H_
#define _TSRC_H_

int main(void);
void test_jojo(void);
void test_ChkPrime(void);
void test_printJojo(void);
void test_printNum(void);

#endif /* _TSRC_H_ */
```

CUnitではテストコードのmain関数でレジストリ初期化などが必要となる
以下の表に簡単に記載した

###CUnit関数



<table class="CUnit function">
  <tr>
    <th>概要</th>
    <th>関数名称</th>
    <th>引数</th>
    <th>備考</th>
  </tr>
  <tr>
    <td>レジストリ初期化</td>
    <td>CU_ErroCode CU_initialize_registry(void)</td>
    <td> void </td>
    <td> </td>
  </tr>
  <tr>
    <td>Suite登録</td>
    <td>CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean)</td>
    <td>第1引数: <br>Suite名称, <br>第2引数: <br>初期化関数, <br>第3引数: <br>終了処理関数<br></td>
    <td>CU_add_test関数の前に実行しなければならない</td>
  </tr>
  <tr>
    <td>Test関数登録</td>
    <td>CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc)</td>
    <td>第1引数: <br>CU_add_suiteの戻り値, <br>第２引数: <br>Test関数名称, <br>第3引数: <br>テスト関数<br></td>
    <td> </td>
  </tr>
  <tr>
    <td>CUit実行</td>
    <td>void CU_console_run_tests(void)</td>
    <td> void </td>
    <td>コンソール実行</td>
  </tr>
  <tr>
    <td>レジストリ削除</td>
    <td>void CU_cleanup_registry(void)</td>
    <td> void </td>
    <td> </td>
  </tr>
</table>

###CUnitコンパイル
コンパイルを実施する場合,CUnitのライブラリをリンクする必要がある
そのためコンパイルコマンドは以下の様になる
<pre>
gcc ./src.c ./tsrc.c -Wall -L/usr/local/lib -lcunit
</pre>


###CUnit実行結果

<pre>
$ ./a.out


     CUnit - A Unit testing framework for C - Version 2.1-2
             http://cunit.sourceforge.net/


***************** CUNIT CONSOLE - MAIN MENU ******************************
(R)un  (S)elect  (L)ist  (A)ctivate  (F)ailures  (O)ptions  (H)elp  (Q)uit
Enter command: r

Running Suite : JojoTestSuite
     Running Test : JojoTestjojo
jojo
jojo
4
jojo
6
jojo
8
9
10

     Running Test : ChkPrimeTest
     Running Test : PrintJojoTest
     Running Test : PrintNumTest

Run Summary:    Type  Total    Ran Passed Failed Inactive
              suites      1      1    n/a      0        0
               tests      4      4      4      0        0
             asserts      8      8      8      0      n/a

Elapsed time =    0.000 seconds
</pre>

Ran:実行テスト
Passed:通過したテスト
Failed:失敗したテスト
Inactive:未実行テスト

上記の内容でCUnitのinstallからテストの実行までできると考える。
何かの参考になれば幸いである。