Japanese -->
SourceForge.jp 200x40(8244bytes)

How to(More...)

  The following typical test cases are introduced in this chapter.   If these are used, a still more advanced test can be performed.

Sequence

  This is the easiest test case. It tests in the following codes. This is the function which does sums. A result is returned to ans. However, this function is foolish. If 100 is exceeded,An error will be returned.
#include "plus.h"

/** Sums are done. A result is returned to ans.
 * However, he is stupid.
 * The numerical value to which he exceeds 100
 * writes except zero to a return value.
 * @param data1 imput paramater 1
 * @param data2 imput paramater 2
 * @param ans return paramater
 * @return 0:normal, Other 0:abnormal
 */
unsigned int plus(
    unsigned int data1,
    unsigned int data2,
    unsigned int *ans) {
    unsigned int max = 100;
    *ans = data1 + data2;
    if ((max <= data1) || (max <= data2) || (max <= *ans)) {
        return 1;
    }
    return 0;
}
  A header file is made in this code. A fool does not write a header file. A sage writes a header file. If you do not write a header file, it will have very bad influence on quality.
#ifndef _PLUS_H_
#define _PLUS_H_

unsigned int plus(
    unsigned int data1,
    unsigned int data2,
    unsigned int *ans);

#endif
  Please put the following description into a header file. This is used for double include prevention. This is common sense.
#ifndef _PLUS_H_
#define _PLUS_H_

  /* text */

#endif
  Please describe the following, when you use C++.
#ifdef __cplusplus
extern "C" {
#endif

  /* text */

#ifdef __cplusplus
}
#endif
  The following is a test code.
  As for the function name to test, "test + function name" is recommended.
  As for the file name to test, "file name + Test" is recommended.
  It is recommended that the file to test and a test file separate a folder.
  Supposing you think that a test is inadequate, a test will be written more.
#include <stdio.h>
#include <testRunner.h>
#include "plus.h"

static unsigned int testPlus(void);

/** Main function. */
int main(void) {
    return (int) testRunner(testPlus);
}

static unsigned int testPlus(void) {
    unsigned int err;
    unsigned int ans;
    unsigned int data1;
    unsigned int data2;
    
    data1 = 1;
    data2 = 1;
    err = plus(data1,data2,&ans); // do Test
    TEST_ASSERT_EQUALS((data1 + data2),(int)ans);
    TEST_ASSERT_EQUALS(err,0);
    
    data1 = 100;
    data2 = 1;
    err = plus(data1,data2,&ans); // do Test
    TEST_ASSERT(err != 0);

    data1 = 0;
    data2 = 0xffffffffu; // -1
    err = plus(data1,data2,&ans); // do Test
    TEST_ASSERT(err != 0);

    data1 = 1;
    data2 = 99;
    err = plus(data1,data2,&ans); // do Test
    TEST_ASSERT(err != 0);
    
    return 0;
}
  If the above is seen, "The test of main() is not made." will understand in CUnit for Mr.Ando.

  If possible,separation of the test enviroment. Mixture is not cool!


Figure : Separation of test folder.


  The following name space is used in CUnit for Mr.Ando.

TEST_ASSERT
NameDescription
TEST_ASSERT(_a) A test is failure when _a is 0.
TEST_ASSERT_EQUALS(_a,_b) A test is success when _a == _b.
TEST_ASSERT_NOT_EQUALS(_a,_b) A test is success when _a != _b.


  The test result is as follows.
$ make run
gcc  -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -c ../real/src/plus.c
gcc  -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -c ./src/plusTest.c
gcc  -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -c ../../CUnitForAndo/src/testRunner.c
gcc  -ggdb -Wall  -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -o ./runExe.exe plus.o plusTest.o testRunner.o
./runExe.exe
OK (5 tests)

  Next, in the following case, it tests using a Mock function. Only caller function can be tested by using Mock function.
#include "plus.h"
#include "sequence.h"

unsigned int sequence(
    unsigned int data1,
    unsigned int data2,
    unsigned int *ans) {
    unsigned int err;
    
    err = plus(data1,data2,ans);
    
    return err;
}
  Next, in the following case, it tests using a Mock function. plus() is set to Mock function in sequence(). Variable inPlus_data1 and inPlus_data2 are prepared for input data. Variable outPlus_ans and returnPlus are prepared for output data.
#include 
#include 
#include "plus.h"
#include "sequence.h"

static unsigned int testSequence(void);


/* test data */
static unsigned int inPlus_data1;
static unsigned int inPlus_data2;
static unsigned int outPlus_ans;
static unsigned int returnPlus;

/** Main function. */
int main(void) {
    return (int) testRunner(testSequence);
}

static unsigned int testSequence(void) {
    unsigned int err;
    unsigned int ans;
    unsigned int data1;
    unsigned int data2;
    
    /////////////////////////////////////////////////
    // Normal test
    data1 = 0; // 0-0xffffffffu
    data2 = 0xffffffffu; // 0-0xffffffffu
    inPlus_data1 = 0xffffffffu; // pollute
    inPlus_data2 = 0xffffffffu; // pollute
    outPlus_ans = 99; // 0-99
    returnPlus = 0; // 0(Normal),1-0xffffffffu(Abnormal)
    
    err = sequence(data1,data2,&ans); // run!
    
    TEST_ASSERT_EQUALS(err,(int)returnPlus);
    TEST_ASSERT_EQUALS(data1,(int)inPlus_data1);
    TEST_ASSERT_EQUALS(data2,(int)inPlus_data2);
    TEST_ASSERT_EQUALS(ans,(int)outPlus_ans);
    
    /////////////////////////////////////////////////
    // Abnormal test
    data1 = 0; // 0-0xffffffffu
    data2 = 0xffffffffu; // 0-0xffffffffu
    inPlus_data1 = 0xffffffffu; // pollute
    inPlus_data2 = 0xffffffffu; // pollute
    outPlus_ans = 1; // 0-99
    returnPlus = 1; // 0(Normal),1-0xffffffffu(Abnormal)
    
    err = sequence(data1,data2,&ans); // run!
    
    TEST_ASSERT_EQUALS(err,(int)returnPlus);
    TEST_ASSERT_EQUALS(data1,(int)inPlus_data1);
    TEST_ASSERT_EQUALS(data2,(int)inPlus_data2);

    return 0;
}

/** driver */
unsigned int plus(
    unsigned int data1,
    unsigned int data2,
    unsigned int *ans) {
    inPlus_data1 = data1;
    inPlus_data2 = data2;
    *ans = outPlus_ans;
    return returnPlus;
}
  plus.c cannot be compiled together. Please prepare another environment. This is restrictions not to make overwrite like Java in the C language.

Figure : Separation of test environment.

selection

  It is the test of if() or switch(). This is a file for a test.
#include "select.h"

/** @see select.h */
unsigned int hardAccsess(
    unsigned int address,
    unsigned int data,
    HARD_TYPE_t select) {
    unsigned int err = 0;
    switch (select) {
    case HARD_TYPE_A:
        err = setDataA(address,data);
        break;
    case HARD_TYPE_B:
    default:
        if ((data & 0xffff0000u) != 0) {
            err = 1;
        } else {
            writeAccessB(address,(unsigned short)data);
        }
        break;
    }
    return err;
}
  This is test file.
#include <stdio.h>
#include <testRunner.h>
#include "select.h"

/* A test is divided. */
static unsigned int testAll(void);
static unsigned int testHardA(void);
static unsigned int testHardB(void);

/* A domain is secured. */
static unsigned int inSetDataA_address;
static unsigned int inSetDataA_data;
static unsigned int returnSetDataA;
static unsigned int inWriteAccessB_address;
static unsigned short inWriteAccessB_data;

int main(int argc,char **argv) {
    return (int) testRunner(testAll);
}

static unsigned int testAll(void) {
    TEST_ASSERT(! testHardA());
    TEST_ASSERT(! testHardB());
    return 0;
}

static unsigned int testHardA(void) {
    unsigned int err;
    unsigned int address;
    unsigned int data;
    HARD_TYPE_t select;
    
    /////////////////////////////////////////////////
    // setDataA normal
    address = 0x85000038u; // 0x0-ffffffffu
    data = 456; // 0x0-ffffffffu
    select = HARD_TYPE_A; // HARD_TYPE_A,HARD_TYPE_B
    inSetDataA_address = 0xffffffffu;// imput(dirty)
    inSetDataA_data = 0xffffffffu;// imput(dirty)
    returnSetDataA = 0; // 0:normal,1-0xffffffffu:abnormal
    inWriteAccessB_address = 0xffffffffu; // imput(dirty)
    inWriteAccessB_data = 0xffffu; // imput(dirty)
    
    err = hardAccsess(address,data,select); // do test
    
    TEST_ASSERT_EQUALS(err,0); // normal
    TEST_ASSERT_EQUALS(inSetDataA_address,(int)address); // Check!
    TEST_ASSERT_EQUALS(inSetDataA_data,(int)data); // Check!
    TEST_ASSERT_EQUALS(inWriteAccessB_address,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inWriteAccessB_data,0xffffu); // no access

    /////////////////////////////////////////////////
    // setDataA abnormal
    address = 0x86540004u; // 0x0-ffffffffu
    data = 22; // 0x0-ffffffffu
    select = HARD_TYPE_A; // HARD_TYPE_A,HARD_TYPE_B
    inSetDataA_address = 0xffffffffu;// imput(dirty)
    inSetDataA_data = 0xffffffffu;// imput(dirty)
    returnSetDataA = 0x31u; // 0:normal,1-0xffffffffu:abnormal
    inWriteAccessB_address = 0xffffffffu; // imput(dirty)
    inWriteAccessB_data = 0xffffu; // imput(dirty)
    
    err = hardAccsess(address,data,select); // do test
    
    TEST_ASSERT(err != 0); // abnormal
    TEST_ASSERT_EQUALS(inSetDataA_address,(int)address); // Check!
    TEST_ASSERT_EQUALS(inSetDataA_data,(int)data); // Check!
    TEST_ASSERT_EQUALS(inWriteAccessB_address,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inWriteAccessB_data,0xffffu); // no access
    return 0;
}

static unsigned int testHardB(void) {
    unsigned int err;
    unsigned int address;
    unsigned int data;
    HARD_TYPE_t select;

    /////////////////////////////////////////////////
    // writeAccessB normal
    address = 0x36540004u; // 0x0-ffffffffu
    data = 22; // 0x0-0000ffffu:normal,0x00010000-0xffff0000:abnormal
    select = HARD_TYPE_B; // HARD_TYPE_A,HARD_TYPE_B
    inSetDataA_address = 0xffffffffu;// imput(dirty)
    inSetDataA_data = 0xffffffffu;// imput(dirty)
    returnSetDataA = 0; // 0:normal,1-0xffffffffu:abnormal
    inWriteAccessB_address = 0xffffffffu; // imput(dirty)
    inWriteAccessB_data = 0xffffu; // imput(dirty)
    
    err = hardAccsess(address,data,select); // do test
    
    TEST_ASSERT_EQUALS(err , 0); // normal
    TEST_ASSERT_EQUALS(inSetDataA_address,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inSetDataA_data,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inWriteAccessB_address,(int)address); // Check!
    TEST_ASSERT_EQUALS(inWriteAccessB_data,data); // Check!
    
    /////////////////////////////////////////////////
    // writeAccessB abnormal
    address = 0x36500027u; // 0x0-ffffffffu
    data = 0x04000003u; // 0x0-0000ffffu:normal,0x00010000-0xffff0000:abnormal
    select = HARD_TYPE_B; // HARD_TYPE_A,HARD_TYPE_B
    inSetDataA_address = 0xffffffffu;// imput(dirty)
    inSetDataA_data = 0xffffffffu;// imput(dirty)
    returnSetDataA = 0; // 0:normal,1-0xffffffffu:abnormal
    inWriteAccessB_address = 0xffffffffu; // imput(dirty)
    inWriteAccessB_data = 0xffffu; // imput(dirty)
    
    err = hardAccsess(address,data,select);
    
    TEST_ASSERT(err != 0); // abnormal
    TEST_ASSERT_EQUALS(inSetDataA_address,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inSetDataA_data,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inWriteAccessB_address,(int)0xffffffffu); // no access
    TEST_ASSERT_EQUALS(inWriteAccessB_data,0xffffu); // no access
    return 0;
}

/** Unit A Access driver. */
unsigned int setDataA(
    unsigned int address,unsigned int data) {
    inSetDataA_address = address;
    inSetDataA_data = data;
    return returnSetDataA;
}

/** Unit B Access driver. */
void writeAccessB(
    unsigned int address,unsigned short data) {
    inWriteAccessB_address = address;
    inWriteAccessB_data = data;
}

Foreach

  This is a file for a test.
#include "select.h"
#include "loop.h"

unsigned int loop(void) {
    unsigned int err;
    unsigned int loopErr = 0;
    unsigned int i = 0;
    for (i = 0 ; i < 10 ; i++) {
        unsigned int address = 0x85000000u + ( i + 8);
        err = setDataA(address,i);
        if (err && (! loopErr)) {
            loopErr = err;
        }
    }
    return loopErr;
}
  This is test file.
#include <stdio.h>
#include <string.h>
#include <testRunner.h>
#include "select.h"
#include "loop.h"

/* A domain is secured. */
#define DATA_ARRAY 100
static unsigned int inSetDataA_address[DATA_ARRAY];
static unsigned int inSetDataA_data[DATA_ARRAY];
static unsigned int returnSetDataA[DATA_ARRAY];
static unsigned int countSetDataA = 0;

static unsigned int testLoop(void);

/** Main function. */
int main() {
    return (int) testRunner(testLoop);
}

static unsigned int testLoop(void) {
    unsigned int err;
    unsigned int i;
    
    /////////////////////////////////////////////////
    // normal
    memset(inSetDataA_address,0xffffffffu,sizeof(unsigned int)*DATA_ARRAY);
    memset(inSetDataA_data,0xffffffffu,sizeof(unsigned int)*DATA_ARRAY);
    memset(returnSetDataA,0,sizeof(unsigned int)*DATA_ARRAY);
    countSetDataA = 0;
    
    err = loop(); // do test
    
    TEST_ASSERT_EQUALS(err,0); // normal
    TEST_ASSERT_EQUALS(countSetDataA,10); //
    for (i = 0 ; i < 10 ; i++) {
        TEST_ASSERT_EQUALS(inSetDataA_address[i] ,(int) (0x85000000u + (i + 8)));
        TEST_ASSERT_EQUALS(inSetDataA_data[i] ,(int) i);
    }

    /////////////////////////////////////////////////
    // abnormal
    memset(inSetDataA_address,0xffffffffu,sizeof(unsigned int)*DATA_ARRAY);
    memset(inSetDataA_data,0xffffffffu,sizeof(unsigned int)*DATA_ARRAY);
    memset(returnSetDataA,0,sizeof(unsigned int)*DATA_ARRAY);
    returnSetDataA[3] = 5; // A mistake is mixed.
    countSetDataA = 0;
    
    err = loop(); // do test
    
    TEST_ASSERT(err != 0); // abnormal
    // Even if there is an error, a hard setup has run
    TEST_ASSERT_EQUALS(countSetDataA,10);
    for (i = 0 ; i < 10 ; i++) {
        TEST_ASSERT_EQUALS(inSetDataA_address[i] ,(int) (0x85000000u + (i + 8)));
        TEST_ASSERT_EQUALS(inSetDataA_data[i] ,(int) i);
    }
    return 0;
}

/** Unit A Access driver. */
unsigned int setDataA(
    unsigned int address,unsigned int data) {
    inSetDataA_address[countSetDataA] = address;
    inSetDataA_data[countSetDataA] = data;
    countSetDataA++;
    return returnSetDataA[countSetDataA];
}

ando@park.ruru.ne.jp