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:
0:0b799af9d58e
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 #ifndef D_TestOutput_h
rgrover1 0:0b799af9d58e 29 #define D_TestOutput_h
rgrover1 0:0b799af9d58e 30
rgrover1 0:0b799af9d58e 31 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 32 //
rgrover1 0:0b799af9d58e 33 // This is a minimal printer inteface.
rgrover1 0:0b799af9d58e 34 // We kept streams out too keep footprint small, and so the test
rgrover1 0:0b799af9d58e 35 // harness could be used with less capable compilers so more
rgrover1 0:0b799af9d58e 36 // platforms could use this test harness
rgrover1 0:0b799af9d58e 37 //
rgrover1 0:0b799af9d58e 38 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 39
rgrover1 0:0b799af9d58e 40 class UtestShell;
rgrover1 0:0b799af9d58e 41 class TestFailure;
rgrover1 0:0b799af9d58e 42 class TestResult;
rgrover1 0:0b799af9d58e 43
rgrover1 0:0b799af9d58e 44 class TestOutput
rgrover1 0:0b799af9d58e 45 {
rgrover1 0:0b799af9d58e 46 public:
rgrover1 0:0b799af9d58e 47 explicit TestOutput();
rgrover1 0:0b799af9d58e 48 virtual ~TestOutput();
rgrover1 0:0b799af9d58e 49
rgrover1 0:0b799af9d58e 50 virtual void printTestsStarted();
rgrover1 0:0b799af9d58e 51 virtual void printTestsEnded(const TestResult& result);
rgrover1 0:0b799af9d58e 52 virtual void printCurrentTestStarted(const UtestShell& test);
rgrover1 0:0b799af9d58e 53 virtual void printCurrentTestEnded(const TestResult& res);
rgrover1 0:0b799af9d58e 54 virtual void printCurrentGroupStarted(const UtestShell& test);
rgrover1 0:0b799af9d58e 55 virtual void printCurrentGroupEnded(const TestResult& res);
rgrover1 0:0b799af9d58e 56
rgrover1 0:0b799af9d58e 57 virtual void verbose();
rgrover1 0:0b799af9d58e 58 virtual void printBuffer(const char*)=0;
rgrover1 0:0b799af9d58e 59 virtual void print(const char*);
rgrover1 0:0b799af9d58e 60 virtual void print(long);
rgrover1 0:0b799af9d58e 61 virtual void printDouble(double);
rgrover1 0:0b799af9d58e 62 virtual void printHex(long);
rgrover1 0:0b799af9d58e 63 virtual void print(const TestFailure& failure);
rgrover1 0:0b799af9d58e 64 virtual void printTestRun(int number, int total);
rgrover1 0:0b799af9d58e 65 virtual void setProgressIndicator(const char*);
rgrover1 0:0b799af9d58e 66
rgrover1 0:0b799af9d58e 67 virtual void flush();
rgrover1 0:0b799af9d58e 68
rgrover1 0:0b799af9d58e 69 enum WorkingEnvironment {vistualStudio, eclipse, detectEnvironment};
rgrover1 0:0b799af9d58e 70
rgrover1 0:0b799af9d58e 71 static void setWorkingEnvironment(WorkingEnvironment workEnvironment);
rgrover1 0:0b799af9d58e 72 static WorkingEnvironment getWorkingEnvironment();
rgrover1 0:0b799af9d58e 73
rgrover1 0:0b799af9d58e 74 protected:
rgrover1 0:0b799af9d58e 75
rgrover1 0:0b799af9d58e 76 virtual void printEclipseErrorInFileOnLine(SimpleString file, int lineNumber);
rgrover1 0:0b799af9d58e 77 virtual void printVistualStudioErrorInFileOnLine(SimpleString file, int lineNumber);
rgrover1 0:0b799af9d58e 78
rgrover1 0:0b799af9d58e 79 virtual void printProgressIndicator();
rgrover1 0:0b799af9d58e 80 void printFileAndLineForTestAndFailure(const TestFailure& failure);
rgrover1 0:0b799af9d58e 81 void printFileAndLineForFailure(const TestFailure& failure);
rgrover1 0:0b799af9d58e 82 void printFailureInTest(SimpleString testName);
rgrover1 0:0b799af9d58e 83 void printFailureMessage(SimpleString reason);
rgrover1 0:0b799af9d58e 84 void printErrorInFileOnLineFormattedForWorkingEnvironment(SimpleString testFile, int lineNumber);
rgrover1 0:0b799af9d58e 85
rgrover1 0:0b799af9d58e 86 TestOutput(const TestOutput&);
rgrover1 0:0b799af9d58e 87 TestOutput& operator=(const TestOutput&);
rgrover1 0:0b799af9d58e 88
rgrover1 0:0b799af9d58e 89 int dotCount_;
rgrover1 0:0b799af9d58e 90 bool verbose_;
rgrover1 0:0b799af9d58e 91 const char* progressIndication_;
rgrover1 0:0b799af9d58e 92
rgrover1 0:0b799af9d58e 93 static WorkingEnvironment workingEnvironment_;
rgrover1 0:0b799af9d58e 94 };
rgrover1 0:0b799af9d58e 95
rgrover1 0:0b799af9d58e 96 TestOutput& operator<<(TestOutput&, const char*);
rgrover1 0:0b799af9d58e 97 TestOutput& operator<<(TestOutput&, long);
rgrover1 0:0b799af9d58e 98
rgrover1 0:0b799af9d58e 99 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 100 //
rgrover1 0:0b799af9d58e 101 // ConsoleTestOutput.h
rgrover1 0:0b799af9d58e 102 //
rgrover1 0:0b799af9d58e 103 // Printf Based Solution
rgrover1 0:0b799af9d58e 104 //
rgrover1 0:0b799af9d58e 105 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 106
rgrover1 0:0b799af9d58e 107 class ConsoleTestOutput: public TestOutput
rgrover1 0:0b799af9d58e 108 {
rgrover1 0:0b799af9d58e 109 public:
rgrover1 0:0b799af9d58e 110 explicit ConsoleTestOutput()
rgrover1 0:0b799af9d58e 111 {
rgrover1 0:0b799af9d58e 112 }
rgrover1 0:0b799af9d58e 113 virtual ~ConsoleTestOutput()
rgrover1 0:0b799af9d58e 114 {
rgrover1 0:0b799af9d58e 115 }
rgrover1 0:0b799af9d58e 116
rgrover1 0:0b799af9d58e 117 virtual void printBuffer(const char* s) _override;
rgrover1 0:0b799af9d58e 118 virtual void flush() _override;
rgrover1 0:0b799af9d58e 119
rgrover1 0:0b799af9d58e 120 private:
rgrover1 0:0b799af9d58e 121 ConsoleTestOutput(const ConsoleTestOutput&);
rgrover1 0:0b799af9d58e 122 ConsoleTestOutput& operator=(const ConsoleTestOutput&);
rgrover1 0:0b799af9d58e 123 };
rgrover1 0:0b799af9d58e 124
rgrover1 0:0b799af9d58e 125 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 126 //
rgrover1 0:0b799af9d58e 127 // StringBufferTestOutput.h
rgrover1 0:0b799af9d58e 128 //
rgrover1 0:0b799af9d58e 129 // TestOutput for test purposes
rgrover1 0:0b799af9d58e 130 //
rgrover1 0:0b799af9d58e 131 ///////////////////////////////////////////////////////////////////////////////
rgrover1 0:0b799af9d58e 132
rgrover1 0:0b799af9d58e 133
rgrover1 0:0b799af9d58e 134 class StringBufferTestOutput: public TestOutput
rgrover1 0:0b799af9d58e 135 {
rgrover1 0:0b799af9d58e 136 public:
rgrover1 0:0b799af9d58e 137 explicit StringBufferTestOutput()
rgrover1 0:0b799af9d58e 138 {
rgrover1 0:0b799af9d58e 139 }
rgrover1 0:0b799af9d58e 140
rgrover1 0:0b799af9d58e 141 virtual ~StringBufferTestOutput();
rgrover1 0:0b799af9d58e 142
rgrover1 0:0b799af9d58e 143 void printBuffer(const char* s) _override
rgrover1 0:0b799af9d58e 144 {
rgrover1 0:0b799af9d58e 145 output += s;
rgrover1 0:0b799af9d58e 146 }
rgrover1 0:0b799af9d58e 147
rgrover1 0:0b799af9d58e 148 void flush() _override
rgrover1 0:0b799af9d58e 149 {
rgrover1 0:0b799af9d58e 150 output = "";
rgrover1 0:0b799af9d58e 151 }
rgrover1 0:0b799af9d58e 152
rgrover1 0:0b799af9d58e 153 const SimpleString& getOutput()
rgrover1 0:0b799af9d58e 154 {
rgrover1 0:0b799af9d58e 155 return output;
rgrover1 0:0b799af9d58e 156 }
rgrover1 0:0b799af9d58e 157
rgrover1 0:0b799af9d58e 158 private:
rgrover1 0:0b799af9d58e 159 SimpleString output;
rgrover1 0:0b799af9d58e 160
rgrover1 0:0b799af9d58e 161 StringBufferTestOutput(const StringBufferTestOutput&);
rgrover1 0:0b799af9d58e 162 StringBufferTestOutput& operator=(const StringBufferTestOutput&);
rgrover1 0:0b799af9d58e 163
rgrover1 0:0b799af9d58e 164 };
rgrover1 0:0b799af9d58e 165
rgrover1 0:0b799af9d58e 166 #endif