CppUTest is a C /C++ based unit xUnit test framework for unit testing and for test-driving your code.

CppUTest

Where to find more information

Getting test reports on the console

You may need to tailor the file src/Platforms/mbed/UtestPlatform.cpp to your needs. In particular, if you want console output, you might want to look at the function PlatformSpecificPutchar().

Quick introduction (some code!)

To write your first test, all you need is a new cpp file with a TEST_GROUP and a TEST, like:

#include "CppUTest/TestHarness.h"

TEST_GROUP(FirstTestGroup)
{
};

TEST(FirstTestGroup, FirstTest)
{
   FAIL("Fail me!");
}

This test will fail.

You can add new tests to the test group by just writing more tests in the file, like this:

TEST(FirstTestGroup, SecondTest)
{
   STRCMP_EQUAL("hello", "world");
   LONGS_EQUAL(1, 2);
   CHECK(false);
}

You do need to trigger the tests from somewhere in your program. It could look something like:

#include "CppUTest/TestRegistry.h"
#include "CppUTest/CommandLineTestRunner.h"

int main(int ac, char** av)
{
    ....
    unsigned failureCount = 0;
    {
        ConsoleTestOutput output;
        CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
        failureCount = runner.runAllTestsMain();
    }

    if (failureCount == 0) {
        console.printf("PASSED\r\n");
    }
    ...
}

For more information, We’d recommend to read the manual or, even better, check some existing tests such as SimpleStringTest or (a bit more complicated) MemoryLeakDetectorTest or the mocking tests or just check out the Cheat Sheet.

Committer:
rgrover1
Date:
Tue Jan 28 09:27:41 2014 +0000
Revision:
0:0b799af9d58e
CppUTest unit test framework.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:0b799af9d58e 1 /*
rgrover1 0:0b799af9d58e 2 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
rgrover1 0:0b799af9d58e 3 * All rights reserved.
rgrover1 0:0b799af9d58e 4 *
rgrover1 0:0b799af9d58e 5 * Redistribution and use in source and binary forms, with or without
rgrover1 0:0b799af9d58e 6 * modification, are permitted provided that the following conditions are met:
rgrover1 0:0b799af9d58e 7 * * Redistributions of source code must retain the above copyright
rgrover1 0:0b799af9d58e 8 * notice, this list of conditions and the following disclaimer.
rgrover1 0:0b799af9d58e 9 * * Redistributions in binary form must reproduce the above copyright
rgrover1 0:0b799af9d58e 10 * notice, this list of conditions and the following disclaimer in the
rgrover1 0:0b799af9d58e 11 * documentation and/or other materials provided with the distribution.
rgrover1 0:0b799af9d58e 12 * * Neither the name of the <organization> nor the
rgrover1 0:0b799af9d58e 13 * names of its contributors may be used to endorse or promote products
rgrover1 0:0b799af9d58e 14 * derived from this software without specific prior written permission.
rgrover1 0:0b799af9d58e 15 *
rgrover1 0:0b799af9d58e 16 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
rgrover1 0:0b799af9d58e 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
rgrover1 0:0b799af9d58e 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
rgrover1 0:0b799af9d58e 19 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
rgrover1 0:0b799af9d58e 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rgrover1 0:0b799af9d58e 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
rgrover1 0:0b799af9d58e 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
rgrover1 0:0b799af9d58e 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
rgrover1 0:0b799af9d58e 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
rgrover1 0:0b799af9d58e 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
rgrover1 0:0b799af9d58e 26 */
rgrover1 0:0b799af9d58e 27
rgrover1 0:0b799af9d58e 28 /******************************************************************************
rgrover1 0:0b799af9d58e 29 *
rgrover1 0:0b799af9d58e 30 * Provides an interface for when working with pure C
rgrover1 0:0b799af9d58e 31 *
rgrover1 0:0b799af9d58e 32 *******************************************************************************/
rgrover1 0:0b799af9d58e 33
rgrover1 0:0b799af9d58e 34 #ifndef D_TestHarness_c_h
rgrover1 0:0b799af9d58e 35 #define D_TestHarness_c_h
rgrover1 0:0b799af9d58e 36
rgrover1 0:0b799af9d58e 37 #include "CppUTestConfig.h"
rgrover1 0:0b799af9d58e 38
rgrover1 0:0b799af9d58e 39 #define CHECK_EQUAL_C_INT(expected,actual) \
rgrover1 0:0b799af9d58e 40 CHECK_EQUAL_C_INT_LOCATION(expected,actual,__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 41
rgrover1 0:0b799af9d58e 42 #define CHECK_EQUAL_C_REAL(expected,actual,threshold) \
rgrover1 0:0b799af9d58e 43 CHECK_EQUAL_C_REAL_LOCATION(expected,actual,threshold,__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 44
rgrover1 0:0b799af9d58e 45 #define CHECK_EQUAL_C_CHAR(expected,actual) \
rgrover1 0:0b799af9d58e 46 CHECK_EQUAL_C_CHAR_LOCATION(expected,actual,__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 47
rgrover1 0:0b799af9d58e 48 #define CHECK_EQUAL_C_STRING(expected,actual) \
rgrover1 0:0b799af9d58e 49 CHECK_EQUAL_C_STRING_LOCATION(expected,actual,__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 50
rgrover1 0:0b799af9d58e 51 #define FAIL_TEXT_C(text) \
rgrover1 0:0b799af9d58e 52 FAIL_TEXT_C_LOCATION(text,__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 53
rgrover1 0:0b799af9d58e 54 #define FAIL_C() \
rgrover1 0:0b799af9d58e 55 FAIL_C_LOCATION(__FILE__,__LINE__)
rgrover1 0:0b799af9d58e 56
rgrover1 0:0b799af9d58e 57 #define CHECK_C(condition) \
rgrover1 0:0b799af9d58e 58 CHECK_C_LOCATION(condition, #condition, __FILE__,__LINE__)
rgrover1 0:0b799af9d58e 59
rgrover1 0:0b799af9d58e 60
rgrover1 0:0b799af9d58e 61 /******************************************************************************
rgrover1 0:0b799af9d58e 62 *
rgrover1 0:0b799af9d58e 63 * TEST macros for in C.
rgrover1 0:0b799af9d58e 64 *
rgrover1 0:0b799af9d58e 65 *******************************************************************************/
rgrover1 0:0b799af9d58e 66
rgrover1 0:0b799af9d58e 67 /* For use in C file */
rgrover1 0:0b799af9d58e 68 #define TEST_GROUP_C_SETUP(group_name) \
rgrover1 0:0b799af9d58e 69 extern void group_##group_name##_setup_wrapper_c(void); \
rgrover1 0:0b799af9d58e 70 void group_##group_name##_setup_wrapper_c()
rgrover1 0:0b799af9d58e 71
rgrover1 0:0b799af9d58e 72 #define TEST_GROUP_C_TEARDOWN(group_name) \
rgrover1 0:0b799af9d58e 73 extern void group_##group_name##_teardown_wrapper_c(void); \
rgrover1 0:0b799af9d58e 74 void group_##group_name##_teardown_wrapper_c()
rgrover1 0:0b799af9d58e 75
rgrover1 0:0b799af9d58e 76 #define TEST_C(group_name, test_name) \
rgrover1 0:0b799af9d58e 77 extern void test_##group_name##_##test_name##_wrapper_c(void);\
rgrover1 0:0b799af9d58e 78 void test_##group_name##_##test_name##_wrapper_c()
rgrover1 0:0b799af9d58e 79
rgrover1 0:0b799af9d58e 80
rgrover1 0:0b799af9d58e 81 /* For use in C++ file */
rgrover1 0:0b799af9d58e 82
rgrover1 0:0b799af9d58e 83 #define TEST_GROUP_C(group_name) \
rgrover1 0:0b799af9d58e 84 extern "C" { \
rgrover1 0:0b799af9d58e 85 extern void group_##group_name##_setup_wrapper_c(void); \
rgrover1 0:0b799af9d58e 86 extern void group_##group_name##_teardown_wrapper_c(void); \
rgrover1 0:0b799af9d58e 87 } \
rgrover1 0:0b799af9d58e 88 TEST_GROUP(group_name)
rgrover1 0:0b799af9d58e 89
rgrover1 0:0b799af9d58e 90 #define TEST_GROUP_C_SETUP_WRAPPER(group_name) \
rgrover1 0:0b799af9d58e 91 void setup() { \
rgrover1 0:0b799af9d58e 92 group_##group_name##_setup_wrapper_c(); \
rgrover1 0:0b799af9d58e 93 }
rgrover1 0:0b799af9d58e 94
rgrover1 0:0b799af9d58e 95 #define TEST_GROUP_C_TEARDOWN_WRAPPER(group_name) \
rgrover1 0:0b799af9d58e 96 void teardown() { \
rgrover1 0:0b799af9d58e 97 group_##group_name##_teardown_wrapper_c(); \
rgrover1 0:0b799af9d58e 98 }
rgrover1 0:0b799af9d58e 99
rgrover1 0:0b799af9d58e 100 #define TEST_GROUP_C_WRAPPER(group_name, test_name) \
rgrover1 0:0b799af9d58e 101 extern "C" { \
rgrover1 0:0b799af9d58e 102 extern void test_##group_name##_##test_name##_wrapper_c(); \
rgrover1 0:0b799af9d58e 103 } \
rgrover1 0:0b799af9d58e 104 TEST(group_name, test_name) { \
rgrover1 0:0b799af9d58e 105 test_##group_name##_##test_name##_wrapper_c(); \
rgrover1 0:0b799af9d58e 106 }
rgrover1 0:0b799af9d58e 107
rgrover1 0:0b799af9d58e 108 #ifdef __cplusplus
rgrover1 0:0b799af9d58e 109 extern "C"
rgrover1 0:0b799af9d58e 110 {
rgrover1 0:0b799af9d58e 111 #endif
rgrover1 0:0b799af9d58e 112
rgrover1 0:0b799af9d58e 113
rgrover1 0:0b799af9d58e 114 /* CHECKS that can be used from C code */
rgrover1 0:0b799af9d58e 115 extern void CHECK_EQUAL_C_INT_LOCATION(int expected, int actual,
rgrover1 0:0b799af9d58e 116 const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 117 extern void CHECK_EQUAL_C_REAL_LOCATION(double expected, double actual,
rgrover1 0:0b799af9d58e 118 double threshold, const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 119 extern void CHECK_EQUAL_C_CHAR_LOCATION(char expected, char actual,
rgrover1 0:0b799af9d58e 120 const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 121 extern void CHECK_EQUAL_C_STRING_LOCATION(const char* expected,
rgrover1 0:0b799af9d58e 122 const char* actual, const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 123 extern void FAIL_TEXT_C_LOCATION(const char* text, const char* fileName,
rgrover1 0:0b799af9d58e 124 int lineNumber);
rgrover1 0:0b799af9d58e 125 extern void FAIL_C_LOCATION(const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 126 extern void CHECK_C_LOCATION(int condition, const char* conditionString,
rgrover1 0:0b799af9d58e 127 const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 128
rgrover1 0:0b799af9d58e 129 extern void* cpputest_malloc(size_t size);
rgrover1 0:0b799af9d58e 130 extern void* cpputest_calloc(size_t num, size_t size);
rgrover1 0:0b799af9d58e 131 extern void* cpputest_realloc(void* ptr, size_t size);
rgrover1 0:0b799af9d58e 132 extern void cpputest_free(void* buffer);
rgrover1 0:0b799af9d58e 133
rgrover1 0:0b799af9d58e 134 extern void* cpputest_malloc_location(size_t size, const char* file, int line);
rgrover1 0:0b799af9d58e 135 extern void* cpputest_calloc_location(size_t num, size_t size,
rgrover1 0:0b799af9d58e 136 const char* file, int line);
rgrover1 0:0b799af9d58e 137 extern void* cpputest_realloc_location(void* memory, size_t size,
rgrover1 0:0b799af9d58e 138 const char* file, int line);
rgrover1 0:0b799af9d58e 139 extern void cpputest_free_location(void* buffer, const char* file, int line);
rgrover1 0:0b799af9d58e 140
rgrover1 0:0b799af9d58e 141 void cpputest_malloc_set_out_of_memory(void);
rgrover1 0:0b799af9d58e 142 void cpputest_malloc_set_not_out_of_memory(void);
rgrover1 0:0b799af9d58e 143 void cpputest_malloc_set_out_of_memory_countdown(int);
rgrover1 0:0b799af9d58e 144 void cpputest_malloc_count_reset(void);
rgrover1 0:0b799af9d58e 145 int cpputest_malloc_get_count(void);
rgrover1 0:0b799af9d58e 146
rgrover1 0:0b799af9d58e 147 #ifdef __cplusplus
rgrover1 0:0b799af9d58e 148 }
rgrover1 0:0b799af9d58e 149 #endif
rgrover1 0:0b799af9d58e 150
rgrover1 0:0b799af9d58e 151
rgrover1 0:0b799af9d58e 152 /*
rgrover1 0:0b799af9d58e 153 * Small additional macro for unused arguments. This is common when stubbing, but in C you cannot remove the
rgrover1 0:0b799af9d58e 154 * name of the parameter (as in C++).
rgrover1 0:0b799af9d58e 155 */
rgrover1 0:0b799af9d58e 156
rgrover1 0:0b799af9d58e 157 #ifndef PUNUSED
rgrover1 0:0b799af9d58e 158 #if defined(__GNUC__)
rgrover1 0:0b799af9d58e 159 # define PUNUSED(x) PUNUSED_ ##x __attribute__((unused))
rgrover1 0:0b799af9d58e 160 #else
rgrover1 0:0b799af9d58e 161 # define PUNUSED(x) x
rgrover1 0:0b799af9d58e 162 #endif
rgrover1 0:0b799af9d58e 163 #endif
rgrover1 0:0b799af9d58e 164
rgrover1 0:0b799af9d58e 165 #endif