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:
Rohit Grover
Date:
Thu Jun 19 08:24:31 2014 +0100
Revision:
2:82161d9e7b36
Parent:
1:4769360130ed
uncomment the code in CommandLineTestRunner::RunAllTests() having to do with MemoryLeakWarningPlugin

Bas Vodde, from the CppUTest development team has suggested an alternate way to run tests.

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 #ifndef CPPUTESTCONFIG_H_
rgrover1 0:0b799af9d58e 30 #define CPPUTESTCONFIG_H_
rgrover1 0:0b799af9d58e 31
rgrover1 0:0b799af9d58e 32 #ifdef HAVE_CONFIG_H
rgrover1 0:0b799af9d58e 33 #include "config.h"
rgrover1 0:0b799af9d58e 34 #endif
rgrover1 0:0b799af9d58e 35
rgrover1 0:0b799af9d58e 36 /*
rgrover1 0:0b799af9d58e 37 * This file is added for some specific CppUTest configurations that earlier were spread out into multiple files.
rgrover1 0:0b799af9d58e 38 *
rgrover1 0:0b799af9d58e 39 * The goal of this file is to stay really small and not to include other things, but mainly to remove duplication
rgrover1 0:0b799af9d58e 40 * from other files and resolve dependencies in #includes.
rgrover1 0:0b799af9d58e 41 *
rgrover1 0:0b799af9d58e 42 */
rgrover1 0:0b799af9d58e 43
rgrover1 0:0b799af9d58e 44 /*
rgrover1 0:0b799af9d58e 45 * Lib C dependencies that are currently still left:
rgrover1 0:0b799af9d58e 46 *
rgrover1 0:0b799af9d58e 47 * stdarg.h -> We use formatting functions and va_list requires to include stdarg.h in SimpleString
rgrover1 0:0b799af9d58e 48 * stdlib.h -> The TestHarness_c.h includes this to try to avoid conflicts in its malloc #define. This dependency can
rgrover1 0:0b799af9d58e 49 * easily be removed by not enabling the MALLOC overrides.
rgrover1 0:0b799af9d58e 50 *
rgrover1 0:0b799af9d58e 51 * Lib C++ dependencies are all under the CPPUTEST_USE_STD_CPP_LIB.
rgrover1 0:0b799af9d58e 52 * The only dependency is to <new> which has the bad_alloc struct
rgrover1 0:0b799af9d58e 53 *
rgrover1 0:0b799af9d58e 54 */
rgrover1 0:0b799af9d58e 55
rgrover1 0:0b799af9d58e 56 /* Do we use Standard C or not? When doing Kernel development, standard C usage is out. */
rgrover1 0:0b799af9d58e 57 #ifndef CPPUTEST_USE_STD_C_LIB
rgrover1 0:0b799af9d58e 58 #ifdef CPPUTEST_STD_C_LIB_DISABLED
rgrover1 0:0b799af9d58e 59 #define CPPUTEST_USE_STD_C_LIB 0
rgrover1 0:0b799af9d58e 60 #else
rgrover1 0:0b799af9d58e 61 #define CPPUTEST_USE_STD_C_LIB 1
rgrover1 0:0b799af9d58e 62 #endif
rgrover1 0:0b799af9d58e 63 #endif
rgrover1 0:0b799af9d58e 64
Rohit Grover 1:4769360130ed 65 #if NEED_TO_ENABLE_CPP_SUPPORT /* disabled by default because our
rgrover1 0:0b799af9d58e 66 * toolchain doesn't support exceptions. */
rgrover1 0:0b799af9d58e 67 /* Do we use Standard C++ or not? */
rgrover1 0:0b799af9d58e 68 #ifndef CPPUTEST_USE_STD_CPP_LIB
rgrover1 0:0b799af9d58e 69 #ifdef CPPUTEST_STD_CPP_LIB_DISABLED
rgrover1 0:0b799af9d58e 70 #define CPPUTEST_USE_STD_CPP_LIB 0
rgrover1 0:0b799af9d58e 71 #else
rgrover1 0:0b799af9d58e 72 #define CPPUTEST_USE_STD_CPP_LIB 1
rgrover1 0:0b799af9d58e 73 #endif
rgrover1 0:0b799af9d58e 74 #endif
rgrover1 0:0b799af9d58e 75 #endif /* #if NEED_TO_ENABLE_CPP_SUPPORT */
rgrover1 0:0b799af9d58e 76
rgrover1 0:0b799af9d58e 77 /* Is memory leak detection enabled?
rgrover1 0:0b799af9d58e 78 * Controls the override of the global operator new/deleted and malloc/free.
rgrover1 0:0b799af9d58e 79 * Without this, there will be no memory leak detection in C/C++.
rgrover1 0:0b799af9d58e 80 */
rgrover1 0:0b799af9d58e 81 #if NEED_TO_ENABLE_MEMORY_LEAK_DETECTION
rgrover1 0:0b799af9d58e 82 #ifndef CPPUTEST_USE_MEM_LEAK_DETECTION
rgrover1 0:0b799af9d58e 83 #ifdef CPPUTEST_MEM_LEAK_DETECTION_DISABLED
rgrover1 0:0b799af9d58e 84 #define CPPUTEST_USE_MEM_LEAK_DETECTION 0
rgrover1 0:0b799af9d58e 85 #else
rgrover1 0:0b799af9d58e 86 #define CPPUTEST_USE_MEM_LEAK_DETECTION 1
rgrover1 0:0b799af9d58e 87 #endif
rgrover1 0:0b799af9d58e 88 #endif
rgrover1 0:0b799af9d58e 89 #endif /* #if NEED_TO_ENABLE_MEMORY_LEAK_DETECTION */
rgrover1 0:0b799af9d58e 90
rgrover1 0:0b799af9d58e 91 /* Create a __no_return__ macro, which is used to flag a function as not returning.
rgrover1 0:0b799af9d58e 92 * Used for functions that always throws for instance.
rgrover1 0:0b799af9d58e 93 *
rgrover1 0:0b799af9d58e 94 * This is needed for compiling with clang, without breaking other compilers.
rgrover1 0:0b799af9d58e 95 */
rgrover1 0:0b799af9d58e 96 #ifndef __has_attribute
rgrover1 0:0b799af9d58e 97 #define __has_attribute(x) 0
rgrover1 0:0b799af9d58e 98 #endif
rgrover1 0:0b799af9d58e 99
rgrover1 0:0b799af9d58e 100 #if __has_attribute(noreturn)
rgrover1 0:0b799af9d58e 101 #define __no_return__ __attribute__((noreturn))
rgrover1 0:0b799af9d58e 102 #else
rgrover1 0:0b799af9d58e 103 #define __no_return__
rgrover1 0:0b799af9d58e 104 #endif
rgrover1 0:0b799af9d58e 105
rgrover1 0:0b799af9d58e 106 #if __has_attribute(format)
rgrover1 0:0b799af9d58e 107 #define __check_format__(type, format_parameter, other_parameters) __attribute__ ((format (type, format_parameter, other_parameters)))
rgrover1 0:0b799af9d58e 108 #else
rgrover1 0:0b799af9d58e 109 #define __check_format__(type, format_parameter, other_parameters) /* type, format_parameter, other_parameters */
rgrover1 0:0b799af9d58e 110 #endif
rgrover1 0:0b799af9d58e 111
rgrover1 0:0b799af9d58e 112 /*
rgrover1 0:0b799af9d58e 113 * When we don't link Standard C++, then we won't throw exceptions as we assume the compiler might not support that!
rgrover1 0:0b799af9d58e 114 */
rgrover1 0:0b799af9d58e 115
rgrover1 0:0b799af9d58e 116 #if CPPUTEST_USE_STD_CPP_LIB
rgrover1 0:0b799af9d58e 117 #if defined(__cplusplus) && __cplusplus >= 201103L
rgrover1 0:0b799af9d58e 118 #define UT_THROW(exception)
rgrover1 0:0b799af9d58e 119 #define UT_NOTHROW noexcept
rgrover1 0:0b799af9d58e 120 #else
rgrover1 0:0b799af9d58e 121 #define UT_THROW(exception) throw (exception)
rgrover1 0:0b799af9d58e 122 #define UT_NOTHROW throw()
rgrover1 0:0b799af9d58e 123 #endif
rgrover1 0:0b799af9d58e 124 #else
rgrover1 0:0b799af9d58e 125 #define UT_THROW(exception)
Rohit Grover 1:4769360130ed 126 #ifdef __clang__
Rohit Grover 1:4769360130ed 127 #define UT_NOTHROW throw()
Rohit Grover 1:4769360130ed 128 #else
Rohit Grover 1:4769360130ed 129 #define UT_NOTHROW
Rohit Grover 1:4769360130ed 130 #endif
rgrover1 0:0b799af9d58e 131 #endif
rgrover1 0:0b799af9d58e 132
rgrover1 0:0b799af9d58e 133 /*
Rohit Grover 1:4769360130ed 134 * Visual C++ doesn't define __cplusplus as C++11 yet (201103), however it doesn't want the throw(exception) either, but
Rohit Grover 1:4769360130ed 135 * it does want throw().
rgrover1 0:0b799af9d58e 136 */
rgrover1 0:0b799af9d58e 137
Rohit Grover 1:4769360130ed 138 #ifdef _MSC_VER
Rohit Grover 1:4769360130ed 139 #undef UT_THROW
Rohit Grover 1:4769360130ed 140 #define UT_THROW(exception)
Rohit Grover 1:4769360130ed 141 #endif
Rohit Grover 1:4769360130ed 142
Rohit Grover 1:4769360130ed 143 #if defined(__cplusplus) && __cplusplus >= 201103L
Rohit Grover 1:4769360130ed 144 #define DEFAULT_COPY_CONSTRUCTOR(classname) classname(const classname &) = default;
Rohit Grover 1:4769360130ed 145 #else
Rohit Grover 1:4769360130ed 146 #define DEFAULT_COPY_CONSTRUCTOR(classname)
rgrover1 0:0b799af9d58e 147 #endif
rgrover1 0:0b799af9d58e 148
rgrover1 0:0b799af9d58e 149 /*
rgrover1 0:0b799af9d58e 150 * g++-4.7 with stdc++11 enabled On MacOSX! will have a different exception specifier for operator new (and thank you!)
rgrover1 0:0b799af9d58e 151 * I assume they'll fix this in the future, but for now, we'll change that here.
rgrover1 0:0b799af9d58e 152 * (This should perhaps also be done in the configure.ac)
rgrover1 0:0b799af9d58e 153 */
rgrover1 0:0b799af9d58e 154
rgrover1 0:0b799af9d58e 155 #ifdef __GXX_EXPERIMENTAL_CXX0X__
rgrover1 0:0b799af9d58e 156 #ifdef __APPLE__
rgrover1 0:0b799af9d58e 157 #ifdef _GLIBCXX_THROW
rgrover1 0:0b799af9d58e 158 #undef UT_THROW
rgrover1 0:0b799af9d58e 159 #define UT_THROW(exception) _GLIBCXX_THROW(exception)
rgrover1 0:0b799af9d58e 160 #endif
rgrover1 0:0b799af9d58e 161 #endif
rgrover1 0:0b799af9d58e 162 #endif
rgrover1 0:0b799af9d58e 163
rgrover1 0:0b799af9d58e 164 /*
rgrover1 0:0b799af9d58e 165 * Detection of different 64 bit environments
rgrover1 0:0b799af9d58e 166 */
rgrover1 0:0b799af9d58e 167
rgrover1 0:0b799af9d58e 168 #if defined(__LP64__) || defined(_LP64) || (defined(__WORDSIZE) && (__WORDSIZE == 64 )) || defined(__x86_64) || defined(_WIN64)
rgrover1 0:0b799af9d58e 169 #define CPPUTEST_64BIT
rgrover1 0:0b799af9d58e 170 #if defined(_WIN64)
rgrover1 0:0b799af9d58e 171 #define CPPUTEST_64BIT_32BIT_LONGS
rgrover1 0:0b799af9d58e 172 #endif
rgrover1 0:0b799af9d58e 173 #endif
rgrover1 0:0b799af9d58e 174
Rohit Grover 1:4769360130ed 175 /* Visual C++ 10.0+ (2010+) supports the override keyword, but doesn't define the C++ version as C++11 */
Rohit Grover 1:4769360130ed 176 #if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600)))
rgrover1 0:0b799af9d58e 177 #define _override override
rgrover1 0:0b799af9d58e 178 #else
rgrover1 0:0b799af9d58e 179 #define _override
rgrover1 0:0b799af9d58e 180 #endif
rgrover1 0:0b799af9d58e 181
rgrover1 0:0b799af9d58e 182 /* Should be the only #include here. Standard C library wrappers */
rgrover1 0:0b799af9d58e 183 #include "StandardCLibrary.h"
rgrover1 0:0b799af9d58e 184
rgrover1 0:0b799af9d58e 185 #endif