CodingFirst

C言語、Perl、JavaScript、最近はPythonも。出来上がったものより、プログラムを書くことが好き。あと、スイーツ。

スポンサーサイト

  • このエントリーをはてなブックマークに追加
  • web拍手 by FC2
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

CUnitでテストしてみる(その3)

  • このエントリーをはてなブックマークに追加
  • web拍手 by FC2

CUnitでテストコードを書く。

テストコード。

test.c

CUnitでテストコードを書く。

テストコード。

test.c:
#include <stdio.h>
#include "CUnit/Basic.h"

FILE* hoge_stdout;
extern int hoge_main(int argc, char*argv[]);
extern int hoge;

int ts1_init(void)
{
  hoge_stdout = tmpfile();
  return 0;
}
int ts1_cleanup(void)
{
  hoge_stdout = stdout;
  return 0;
}

void case1(void)
{
  int argc=1;
  char* argv[1] = { "hoge.c" };
  int ret;
  ret=hoge_main(argc,argv);
  CU_ASSERT(hoge==10);
  CU_ASSERT(ret==0);
}

CU_ErrorCode ts1_add(void)
{
    CU_TestInfo cases[] = {
        { "case1" , case1 },
        CU_TEST_INFO_NULL
    };
    CU_SuiteInfo suites[] = {
        { "test of suite1", ts1_init, ts1_cleanup, cases },
        CU_SUITE_INFO_NULL
    };
    return CU_register_suites( suites );
}

int main(int argc, char *argv[])
{
  unsigned int fails;
  if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error();
  if (CUE_SUCCESS != ts1_add() ) return CU_get_error();
  CU_basic_set_mode(CU_BRM_VERBOSE);
  CU_basic_run_tests();
  fails = CU_get_number_of_failures();
  CU_cleanup_registry();
#if 0
  if ( fails > 0 ) {
    fprintf( stderr, "Error: number of failures = %d\n", fails );
    return 1;
  }
#endif
  return CU_get_error();
}

コンパイル。

$ gcc -DTEST -ftest-coverage -fprofile-arcs hoge.c test.c -LCUnit -lcunit
hoge.c:6:1: warning: "stdout" redefined
In file included from hoge.c:1:
/usr/include/stdio.h:241:1: warning: this is the location of the previous definition

うん。ちょっと強引に書きすぎたとこが Warningでてるが、

テストに影響ないので放置する。

$ ./a.out


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


Suite: test of suite1
  Test: case1 ... passed

--Run Summary: Type      Total     Ran  Passed  Failed
               suites        1       1     n/a       0
               tests         1       1       1       0
               asserts       2       2       2       0

$ gcov hoge.c
File 'hoge.c'
Lines executed:54.55% of 11
hoge.c:creating 'hoge.c.gcov'

55%か。テストケースを追加してカバレッジを上げる。

#include &#60;stdio.h>
 #include "CUnit/Basic.h"
 
 FILE* hoge_stdout;
 extern int hoge_main(int argc, char*argv[]);
 extern int hoge;
 
 int ts1_init(void)
 {
   hoge=10;
   hoge_stdout = tmpfile();
   return 0;
 }
 int ts1_cleanup(void)
 {
   hoge=10;
   hoge_stdout = stdout;
   return 0;
 }
 
 void case1(void)
 {
   int argc=1;
   char* argv[1] = { "hoge.c" };
   int ret;
   ret=hoge_main(argc,argv);
   CU_ASSERT(hoge==10);
   CU_ASSERT(ret==0);
 }
+void case2(void)
+{
+  int argc=2;
+  char* argv[2] = { "hoge.c", "10" };
+  int ret;
+  ret=hoge_main(argc,argv);
+  CU_ASSERT(hoge==20);
+  CU_ASSERT(ret==0);
+  hoge=10;
+}
+void case3(void)
+{
+  int argc=3;
+  char* argv[3] = { "hoge.c", "10", "20" };
+  int ret=hoge_main(argc,argv);
+  CU_ASSERT(hoge==10);
+  CU_ASSERT(ret==1);
+}
 
 CU_ErrorCode ts1_add(void)
 {
     CU_TestInfo cases[] = {
         { "case1" , case1 },
+        { "case2" , case2 },
+        { "case3" , case3 },
         CU_TEST_INFO_NULL
     };
     CU_SuiteInfo suites[] = {
         { "test of suite1", ts1_init, ts1_cleanup, cases },
         CU_SUITE_INFO_NULL
     };
     return CU_register_suites( suites );
 }
 
 int main(int argc, char *argv[])
 {
   unsigned int fails;
   if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error();
   if (CUE_SUCCESS != ts1_add() ) return CU_get_error();
   CU_basic_set_mode(CU_BRM_VERBOSE);
   CU_basic_run_tests();
   fails = CU_get_number_of_failures();
   CU_cleanup_registry();
 #if 0
   if ( fails > 0 ) {
     fprintf( stderr, "Error: number of failures = %d\n", fails );
     return 1;
   }
 #endif
   return CU_get_error();
 }

テスト。

$ rm *.g* a.out
$ gcc -DTEST -ftest-coverage -fprofile-arcs hoge.c test.c -LCUnit -lcunit
hoge.c:6:1: warning: "stdout" redefined
In file included from hoge.c:1:
/usr/include/stdio.h:241:1: warning: this is the location of the previous definition
$ ./a.out


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


Suite: test of suite1
  Test: case1 ... passed
  Test: case2 ... passed
  Test: case3 ... passed

--Run Summary: Type      Total     Ran  Passed  Failed
               suites        1       1     n/a       0
               tests         3       3       3       0
               asserts       6       6       6       0
$ gcov hoge.c
File 'hoge.c'
Lines executed:100.00% of 11
hoge.c:creating 'hoge.c.gcov'

$ cat hoge.c.gcov
        -:    0:Source:hoge.c
        -:    0:Graph:hoge.gcno
        -:    0:Data:hoge.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include &#60;stdio.h>
        -:    2:#include &#60;stdlib.h>
        -:    3:#ifdef TEST
        -:    4:extern FILE* hoge_stdout;
        -:    5:#define main hoge_main
        -:    6:#define stdout hoge_stdout
        -:    7:#endif
        -:    8:
        -:    9:int hoge=10;
        -:   10:int help(void)
        1:   11:{
        1:   12:  fprintf(stdout,"hello\n.");
        1:   13:  return 0;
        -:   14:}
        -:   15:int main(int argc, char*argv[])
        3:   16:{
        3:   17:  switch(argc){
        -:   18:  case 1:
        1:   19:    return help();
        -:   20:  case 2:
        1:   21:    hoge += atoi(argv[1]);
        1:   22:    fprintf(stdout,"hoge=%d\n",hoge);
        1:   23:    return 0;
        -:   24:  default:
        1:   25:    fprintf(stdout,"error\n");
        1:   26:    return 1;
        -:   27:  }
        -:   28:}

よし。100%達成。

まとめ。

assert主体でテスト書くのでわかりやすくていいな。テストしてみるとテストしづらい事に気づいてテストしやすいコードを書く癖がつく。その際、シンプルに、他モジュールに依存しないようにする事が多く、良い設計に繋がるように思う。

ただなぁ...。ライブラリビルドするのがめんどくさいなぁ。MinUnit みたいな方が小回りが聞いていいかも知んないな。。


実例で学ぶGCCの本格的活用法―高機能コンパイラのオプション・コマンドを一つ一つていねいに解説 (TECHI―Embedded Software)実例で学ぶGCCの本格的活用法―高機能コンパイラのオプション・コマンドを一つ一つていねいに解説 (TECHI―Embedded Software)
(2006/07)
岸 哲夫

商品詳細を見る

«  | HOME |  »

Search

Recent Entries

Foot Print



Categories

Monthly

Recent Comments

Recent Trackbacks

Profile

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。