2013-11-18

[CUnit] CUnit 사용법


CUnit 사용법에 대해 알아본다. CUnit은 모듈의 기능 테스트에 적합한 것 같다.

CUnit설치 방법은 이전 게시물을 참고한다.
CUnit 설치 방법

아래 페이지를 참고하여 작성하였다. 아래 페이지 내용의 일부분으로 API 중 자주 사용할 것 같은 부분이나 CUnit 설명들 필요한 부분만 작성하였다.
http://cunit.sourceforge.net/doc/index.html

1. 테스트 구조
CUnit의 테스트 구조는 아래와 같다.
Registry가 있고, Registry내부에 Suite들이 존재한다. 그리고 Suite내부에 Test들이 존재한다.

                      Test Registry
                            |
             ------------------------------
             |                            |
          Suite '1'      . . . .       Suite 'N'
             |                            |
       ---------------             ---------------
       |             |             |             |
    Test '11' ... Test '1M'     Test 'N1' ... Test 'NM'

2. 일반적인 사용법
  1) 테스트 함수 작성 (필요에 따라서 Initialize, Cleanup함수도 작성)
  2) Registry에 등록 (CU_initialize_registry() 사용)
  3) Registry에 Suite 등록 (CU_add_suite() 사용)
  4) Suite에 Test 등록 (CU_add_test() 사용)
  5) Running모드 함수 사용 (CU_console_run_tests() 등)
  6) Registry 초기화 (CU_cleanup_registry() 사용)

3. Registry API
  1) CU_ErrorCode CU_initialize_registry(void)
  다른 CUnit 함수들을 사용전에 반드시 사용되어야한다.
  Return Value
  CUE_SUCCESS initialization was successful.
  CUE_NOMEMORY memory allocation failed.

  사용 예)
    if (CUE_SUCCESS != CU_initialize_registry())
        return CU_get_error();

  2) void CU_cleanup_registry(void)
  테스트가 완료되면 메모리를 반환하기 위하여 사용한다.
  사용 예)
    CU_cleanup_registry();

4. Suite API
  CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean)
  Suite를 생성한다. 생성된 Suite는 자동으로 Registry에 등록된다. pInit과 pClean은  0를 return하면 Success로 처리되고, 0이 아니면 fail로 처리되는 파라미터가 없는 함수를 사용한다. Optional하며 불필요시 NULL을 준다.
  Return Value
  CUE_SUCCESS suite creation was successful.
  CUE_NOREGISTRY the registry has not been initialized.
  CUE_NO_SUITENAME strName was NULL.
  CUE_DUP_SUITE the suite's name was not unique.
  CUE_NOMEMORY memory allocation failed.

  사용 예)
    pSuite = CU_add_suite("Suite_1", init_suite1, clean_suite1);
    if (NULL == pSuite) {
        CU_cleanup_registry();
        return CU_get_error();
    }

5. Test 등록 API
  CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc)
  Suite에 Test를 등록시 사용한다.
  Return Value 
  CUE_SUCCESS suite creation was successful.
  CUE_NOSUITE the specified suite was NULL or invalid.
  CUE_NO_TESTNAME strName was NULL.
  CUE_NO_TEST pTestFunc was NULL or invalid.
  CUE_DUP_TEST the test's name was not unique.
  CUE_NOMEMORY memory allocation failed.

  사용 예)
    if ((NULL == CU_add_test(pSuite, "test of fprintf()", testFPRINTF)) )
    {
        CU_cleanup_registry();
        return CU_get_error();
    }

6. Test API
다음은 CUnit에서 제공하는 Test용 API다.
#include <CUnit/CUnit.h>
CU_ASSERT(int expression)
CU_ASSERT_FATAL(int expression)
CU_TEST(int expression)
CU_TEST_FATAL(int expression)
Assert that expression is TRUE (non-zero)
CU_ASSERT_TRUE(value)
CU_ASSERT_TRUE_FATAL(value)
Assert that value is TRUE (non-zero)
CU_ASSERT_FALSE(value)
CU_ASSERT_FALSE_FATAL(value)
Assert that value is FALSE (zero)
CU_ASSERT_EQUAL(actual, expected)
CU_ASSERT_EQUAL_FATAL(actual, expected)
Assert that actual = = expected
CU_ASSERT_NOT_EQUAL(actual, expected))
CU_ASSERT_NOT_EQUAL_FATAL(actual, expected)
Assert that actual != expected
CU_ASSERT_PTR_EQUAL(actual, expected)
CU_ASSERT_PTR_EQUAL_FATAL(actual, expected)
Assert that pointers actual = = expected
CU_ASSERT_PTR_NOT_EQUAL(actual, expected)
CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected)
Assert that pointers actual != expected
CU_ASSERT_PTR_NULL(value)
CU_ASSERT_PTR_NULL_FATAL(value)
Assert that pointer value == NULL
CU_ASSERT_PTR_NOT_NULL(value)
CU_ASSERT_PTR_NOT_NULL_FATAL(value)
Assert that pointer value != NULL
CU_ASSERT_STRING_EQUAL(actual, expected)
CU_ASSERT_STRING_EQUAL_FATAL(actual, expected)
Assert that strings actual and expected are equivalent
CU_ASSERT_STRING_NOT_EQUAL(actual, expected)
CU_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected)
Assert that strings actual and expected differ
CU_ASSERT_NSTRING_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count)
Assert that 1st count chars of actual and expected are the same
CU_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count)
Assert that 1st count chars of actual and expected differ
CU_ASSERT_DOUBLE_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity)
Assert that |actual - expected| <= |granularity|
Math library must be linked in for this assertion.
CU_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity)
Assert that |actual - expected| > |granularity|
Math library must be linked in for this assertion.
CU_PASS(message) Register a passing assertion with the specified message. No logical test is performed.
CU_FAIL(message)
CU_FAIL_FATAL(message)
Register a failed assertion with the specified message. No logical test is performed.

7. Runnting Test API
  Running Test Mode는 다음과 같이 네가지 Mode가 있다.
InterfacePlatformDescription
Automatedallnon-interactive with output to xml files
Basicallnon-interactive with optional output to stdout
Consoleallinteractive console mode under user control
CursesLinux/Unixinteractive curses mode under user control

  1) Automated
  void CU_automated_run_tests(void)
  테스트 결과가 XML 파일로 출력된다.

  2) Basic
  CU_ErrorCode CU_basic_run_tests(void)
  테스트 결과가 stdout 으로 출력된다.

  3) Console
  void CU_console_run_tests(void)
  테스트를 command ui 형태로 할 수 있다. (삼국지2 처럼 한글자 입력하는 형태)

  4) Curses
  void CU_curses_run_tests(void)
  테스트를 curses ui 형태로 할 수 있다. (테스트를 안해봐서 어떤 형태인지 잘 모르겠다)





2013-11-15

[CUnit] CUnit 설치 방법

2013-11-14 최초 작성
2014-11-27 configure 파일 미존재시 automake로  configure 파일 생성 방법 추가
                   라이브러리 제거 방법 추가

1. CUnit 이란?
c로 작성된 소스에 대해서 unit 테스트를 지원해주는 라이브러리이다.

아래 경로는 CUnit 홈페이지다.
http://cunit.sourceforge.net/

2. CUnit 소스 설치

2-1. 준비
OS : Ubuntu 12.04.3 LTS 64bit
CUnit 소스 : 아래 경로에서 CUnit 소스 코드를 다운로드 받을 수 있다.
2013-11-14 기준으로 최신 버전인 CUnit-2.1-2-src.tar.bz2를 다운로드 했다.
http://sourceforge.net/projects/cunit/

** 2014-11-27 기준으로 최신 버전인 CUnit-2.1-3.tar.bz2 까지 설치 됨을 확인 했다.

2-2. 압축 해제
# tar -nxvf CUnit-2.1-2-src.tar.bz2

2-3. configure 파일 존재 여부 확인
# cd CUnit-2.1-2
# ls -l configure

>> 다음 에러 발생시 configure 파일이 미존재. 2-4를 진행한다. <<
ls: configure에 접근할 수 없습니다: 그런 파일이나 디렉터리가 없습니다

>> 다음과 같이 출력되면 configure 파일이 존재. 2-5를 진행한다. <<
-rwxrwxr-x 1 core core 429635 11월 27 00:03 configure

2-4. configure 파일이 없는 경우. automake 로 configure 파일을 생성
# cd CUnit-2.1-2
# aclocal
# autoconf
# autoreconf --install    (2-8 에러 발생시 사용)
# automake                   (2-7 에러 발생 시 automake --add-missing를 사용)
# chmod u+x configure   (실행 권한이 없는 경우 사용한다)

2-5. 빌드 및 설치
# cd CUnit-2.1-2
# ./configure
# make
# sudo make install

2-6. 만약 2-4 진행 중 다음과 같은 에러가 발생한 경우. libtool를 설치 한다.
에러> possibly undefined macro: AC_PROG_LIBTOOL
         If this token and others are legitimate, please use m4_pattern_allow.
         See the Autoconf documentation.

해결> 아래 명령 실행 후 2-4 다시 수행
# sudo apt-get install libtool

2-7. 만약 2-4 진행 중 다음과 같은 에러가 발생한 경우.
에러> required file `./install-sh' not found
          `automake --add-missing' can install `./install-sh`

해결> 2-4에서 "automake" 대신 "automake --add-missing"를 사용한다.
        # automake --add-missing

2-8. 만약, automake 시 `config.h.in' not found 에러가 발생하는 경우.
에러> required file `config.h.in' not found

해결> automake 전에 autoreconf를 사용한다.
        # autoreconf --install
        # automake           (2-7 에러 발생 시 automake --add-missing를 사용)

3. 설치 확인
3.1 라이브러리 확인
# ls -l /usr/local/lib/libcunit*
-rw-r--r-- 1 root root 117126 11월 15 11:18 /usr/local/lib/libcunit.a
-rwxr-xr-x 1 root root   1003 11월 15 11:18 /usr/local/lib/libcunit.la
lrwxrwxrwx 1 root root     17 11월 15 11:18 /usr/local/lib/libcunit.so -> libcunit.so.1.0.1
lrwxrwxrwx 1 root root     17 11월 15 11:18 /usr/local/lib/libcunit.so.1 -> libcunit.so.1.0.1
-rwxr-xr-x 1 root root  78529 11월 15 11:18 /usr/local/lib/libcunit.so.1.0.1

3-2. CUnit 홈페이지에 있는 예제 소스를 이용하여 테스트를 한다.
아래 경로에서 소스를 복사 붙이기 하여 example.c 파일을 만든다.
http://cunit.sourceforge.net/example.html

3-3. example.c를 빌드를 한다.
# gcc -o test example.c -lcunit

3-4. 빌드한 파일을 실행한다.
# ./test

결과 ***************************************
     CUnit - A unit testing framework for C - Version 2.1-2
     http://cunit.sourceforge.net/


Suite: Suite_1
  Test: test of fprintf() ...passed
  Test: test of fread() ...passed

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

Elapsed time =    0.000 seconds
********************************************

3-5. 만약 아래와 같은 오류 발생시 ldconfig 명령을 사용하여 동적 라이브러리를 등록한다.
에러> ./test: error while loading shared libraries: libcunit.so.1: cannot open shared object file: No such file or directory

해결> 아래 명령어 실행 후 3-3, 3-4 다시 수행
          # sudo ldconfig

4. 라이브러리 제거
1~3 과정으로 설치된 라이브러리를 제거한다.
# cd CUnit-2.1-2
# sudo make uninstall