Unit Testing framework based on http://cpputest.github.io/

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 // This file contains the Test class along with the macros which make effective
rgrover1 0:0b799af9d58e 29 // in the harness.
rgrover1 0:0b799af9d58e 30
rgrover1 0:0b799af9d58e 31 #ifndef D_UTest_h
rgrover1 0:0b799af9d58e 32 #define D_UTest_h
rgrover1 0:0b799af9d58e 33
rgrover1 0:0b799af9d58e 34 #include "SimpleString.h"
rgrover1 0:0b799af9d58e 35
rgrover1 0:0b799af9d58e 36 class TestResult;
rgrover1 0:0b799af9d58e 37 class TestPlugin;
rgrover1 0:0b799af9d58e 38 class TestFailure;
rgrover1 0:0b799af9d58e 39 class TestFilter;
rgrover1 0:0b799af9d58e 40 class TestTerminator;
rgrover1 0:0b799af9d58e 41
rgrover1 0:0b799af9d58e 42 extern bool doubles_equal(double d1, double d2, double threshold);
rgrover1 0:0b799af9d58e 43
rgrover1 0:0b799af9d58e 44 //////////////////// Utest
rgrover1 0:0b799af9d58e 45
rgrover1 0:0b799af9d58e 46 class UtestShell;
rgrover1 0:0b799af9d58e 47
rgrover1 0:0b799af9d58e 48 class Utest
rgrover1 0:0b799af9d58e 49 {
rgrover1 0:0b799af9d58e 50 public:
rgrover1 0:0b799af9d58e 51 Utest();
rgrover1 0:0b799af9d58e 52 virtual ~Utest();
rgrover1 0:0b799af9d58e 53 virtual void run();
rgrover1 0:0b799af9d58e 54
rgrover1 0:0b799af9d58e 55 virtual void setup();
rgrover1 0:0b799af9d58e 56 virtual void teardown();
rgrover1 0:0b799af9d58e 57 virtual void testBody();
rgrover1 0:0b799af9d58e 58 };
rgrover1 0:0b799af9d58e 59
rgrover1 0:0b799af9d58e 60 //////////////////// TestTerminator
rgrover1 0:0b799af9d58e 61
rgrover1 0:0b799af9d58e 62 class TestTerminator
rgrover1 0:0b799af9d58e 63 {
rgrover1 0:0b799af9d58e 64 public:
rgrover1 0:0b799af9d58e 65 virtual void exitCurrentTest() const=0;
rgrover1 0:0b799af9d58e 66 virtual ~TestTerminator();
rgrover1 0:0b799af9d58e 67 };
rgrover1 0:0b799af9d58e 68
rgrover1 0:0b799af9d58e 69 class NormalTestTerminator : public TestTerminator
rgrover1 0:0b799af9d58e 70 {
rgrover1 0:0b799af9d58e 71 public:
rgrover1 0:0b799af9d58e 72 virtual void exitCurrentTest() const _override;
rgrover1 0:0b799af9d58e 73 virtual ~NormalTestTerminator();
rgrover1 0:0b799af9d58e 74 };
rgrover1 0:0b799af9d58e 75
rgrover1 0:0b799af9d58e 76 class TestTerminatorWithoutExceptions : public TestTerminator
rgrover1 0:0b799af9d58e 77 {
rgrover1 0:0b799af9d58e 78 public:
rgrover1 0:0b799af9d58e 79 virtual void exitCurrentTest() const _override;
rgrover1 0:0b799af9d58e 80 virtual ~TestTerminatorWithoutExceptions();
rgrover1 0:0b799af9d58e 81 };
rgrover1 0:0b799af9d58e 82
rgrover1 0:0b799af9d58e 83 //////////////////// UtestShell
rgrover1 0:0b799af9d58e 84
rgrover1 0:0b799af9d58e 85 class UtestShell
rgrover1 0:0b799af9d58e 86 {
rgrover1 0:0b799af9d58e 87 public:
rgrover1 0:0b799af9d58e 88 static UtestShell *getCurrent();
rgrover1 0:0b799af9d58e 89
rgrover1 0:0b799af9d58e 90 public:
rgrover1 0:0b799af9d58e 91 UtestShell(const char* groupName, const char* testName, const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 92 virtual ~UtestShell();
rgrover1 0:0b799af9d58e 93
rgrover1 0:0b799af9d58e 94 virtual UtestShell* addTest(UtestShell* test);
rgrover1 0:0b799af9d58e 95 virtual UtestShell *getNext() const;
rgrover1 0:0b799af9d58e 96 virtual bool isNull() const;
rgrover1 0:0b799af9d58e 97 virtual int countTests();
rgrover1 0:0b799af9d58e 98
rgrover1 0:0b799af9d58e 99 bool shouldRun(const TestFilter& groupFilter, const TestFilter& nameFilter) const;
rgrover1 0:0b799af9d58e 100 const SimpleString getName() const;
rgrover1 0:0b799af9d58e 101 const SimpleString getGroup() const;
rgrover1 0:0b799af9d58e 102 virtual SimpleString getFormattedName() const;
rgrover1 0:0b799af9d58e 103 const SimpleString getFile() const;
rgrover1 0:0b799af9d58e 104 int getLineNumber() const;
rgrover1 0:0b799af9d58e 105 virtual const char *getProgressIndicator() const;
rgrover1 0:0b799af9d58e 106 virtual bool hasFailed() const;
rgrover1 0:0b799af9d58e 107
rgrover1 0:0b799af9d58e 108 virtual void assertTrue(bool condition, const char *checkString, const char *conditionString, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 109 virtual void assertTrueText(bool condition, const char *checkString, const char *conditionString, const char* text, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 110 virtual void assertCstrEqual(const char *expected, const char *actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 111 virtual void assertCstrNoCaseEqual(const char *expected, const char *actual, const char *fileName, int lineNumber);
rgrover1 0:0b799af9d58e 112 virtual void assertCstrContains(const char *expected, const char *actual, const char *fileName, int lineNumber);
rgrover1 0:0b799af9d58e 113 virtual void assertCstrNoCaseContains(const char *expected, const char *actual, const char *fileName, int lineNumber);
Rohit Grover 1:4769360130ed 114 virtual void assertLongsEqual(long expected, long actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
Rohit Grover 1:4769360130ed 115 virtual void assertUnsignedLongsEqual(unsigned long expected, unsigned long actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 116 virtual void assertPointersEqual(const void *expected, const void *actual, const char *fileName, int lineNumber);
rgrover1 0:0b799af9d58e 117 virtual void assertDoublesEqual(double expected, double actual, double threshold, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 118 virtual void assertEquals(bool failed, const char* expected, const char* actual, const char* file, int line, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 119 virtual void fail(const char *text, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
rgrover1 0:0b799af9d58e 120
rgrover1 0:0b799af9d58e 121 virtual void print(const char *text, const char *fileName, int lineNumber);
rgrover1 0:0b799af9d58e 122 virtual void print(const SimpleString & text, const char *fileName, int lineNumber);
rgrover1 0:0b799af9d58e 123
rgrover1 0:0b799af9d58e 124 void setFileName(const char *fileName);
rgrover1 0:0b799af9d58e 125 void setLineNumber(int lineNumber);
rgrover1 0:0b799af9d58e 126 void setGroupName(const char *groupName);
rgrover1 0:0b799af9d58e 127 void setTestName(const char *testName);
rgrover1 0:0b799af9d58e 128
rgrover1 0:0b799af9d58e 129 static void crash();
rgrover1 0:0b799af9d58e 130 static void setCrashMethod(void (*crashme)());
rgrover1 0:0b799af9d58e 131 static void resetCrashMethod();
rgrover1 0:0b799af9d58e 132
rgrover1 0:0b799af9d58e 133 virtual bool isRunInSeperateProcess() const;
rgrover1 0:0b799af9d58e 134 virtual void setRunInSeperateProcess();
rgrover1 0:0b799af9d58e 135
rgrover1 0:0b799af9d58e 136 virtual Utest* createTest();
rgrover1 0:0b799af9d58e 137 virtual void destroyTest(Utest* test);
rgrover1 0:0b799af9d58e 138
rgrover1 0:0b799af9d58e 139 virtual void runOneTest(TestPlugin* plugin, TestResult& result);
rgrover1 0:0b799af9d58e 140 virtual void runOneTestInCurrentProcess(TestPlugin *plugin, TestResult & result);
rgrover1 0:0b799af9d58e 141
rgrover1 0:0b799af9d58e 142 virtual void failWith(const TestFailure& failure);
rgrover1 0:0b799af9d58e 143 virtual void failWith(const TestFailure& failure, const TestTerminator& terminator);
rgrover1 0:0b799af9d58e 144
rgrover1 0:0b799af9d58e 145 protected:
rgrover1 0:0b799af9d58e 146 UtestShell();
rgrover1 0:0b799af9d58e 147 UtestShell(const char *groupName, const char *testName, const char *fileName, int lineNumber, UtestShell *nextTest);
rgrover1 0:0b799af9d58e 148
rgrover1 0:0b799af9d58e 149 virtual SimpleString getMacroName() const;
rgrover1 0:0b799af9d58e 150 TestResult *getTestResult();
rgrover1 0:0b799af9d58e 151 private:
rgrover1 0:0b799af9d58e 152 const char *group_;
rgrover1 0:0b799af9d58e 153 const char *name_;
rgrover1 0:0b799af9d58e 154 const char *file_;
rgrover1 0:0b799af9d58e 155 int lineNumber_;
rgrover1 0:0b799af9d58e 156 UtestShell *next_;
rgrover1 0:0b799af9d58e 157 bool isRunAsSeperateProcess_;
rgrover1 0:0b799af9d58e 158 bool hasFailed_;
rgrover1 0:0b799af9d58e 159
rgrover1 0:0b799af9d58e 160 void setTestResult(TestResult* result);
rgrover1 0:0b799af9d58e 161 void setCurrentTest(UtestShell* test);
rgrover1 0:0b799af9d58e 162
rgrover1 0:0b799af9d58e 163 static UtestShell* currentTest_;
rgrover1 0:0b799af9d58e 164 static TestResult* testResult_;
rgrover1 0:0b799af9d58e 165
rgrover1 0:0b799af9d58e 166 };
rgrover1 0:0b799af9d58e 167
rgrover1 0:0b799af9d58e 168 //////////////////// NullTest
rgrover1 0:0b799af9d58e 169
rgrover1 0:0b799af9d58e 170 class NullTestShell: public UtestShell
rgrover1 0:0b799af9d58e 171 {
rgrover1 0:0b799af9d58e 172 public:
rgrover1 0:0b799af9d58e 173 explicit NullTestShell();
rgrover1 0:0b799af9d58e 174 explicit NullTestShell(const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 175 virtual ~NullTestShell();
rgrover1 0:0b799af9d58e 176
rgrover1 0:0b799af9d58e 177 void testBody();
rgrover1 0:0b799af9d58e 178
rgrover1 0:0b799af9d58e 179 static NullTestShell& instance();
rgrover1 0:0b799af9d58e 180
rgrover1 0:0b799af9d58e 181 virtual int countTests() _override;
rgrover1 0:0b799af9d58e 182 virtual UtestShell*getNext() const _override;
rgrover1 0:0b799af9d58e 183 virtual bool isNull() const _override;
rgrover1 0:0b799af9d58e 184 private:
rgrover1 0:0b799af9d58e 185
rgrover1 0:0b799af9d58e 186 NullTestShell(const NullTestShell&);
rgrover1 0:0b799af9d58e 187 NullTestShell& operator=(const NullTestShell&);
rgrover1 0:0b799af9d58e 188
rgrover1 0:0b799af9d58e 189 };
rgrover1 0:0b799af9d58e 190
rgrover1 0:0b799af9d58e 191 //////////////////// ExecFunctionTest
rgrover1 0:0b799af9d58e 192
rgrover1 0:0b799af9d58e 193 class ExecFunctionTestShell;
rgrover1 0:0b799af9d58e 194
rgrover1 0:0b799af9d58e 195 class ExecFunctionTest : public Utest
rgrover1 0:0b799af9d58e 196 {
rgrover1 0:0b799af9d58e 197 public:
rgrover1 0:0b799af9d58e 198 ExecFunctionTest(ExecFunctionTestShell* shell);
rgrover1 0:0b799af9d58e 199 void testBody();
rgrover1 0:0b799af9d58e 200 virtual void setup() _override;
rgrover1 0:0b799af9d58e 201 virtual void teardown() _override;
rgrover1 0:0b799af9d58e 202 private:
rgrover1 0:0b799af9d58e 203 ExecFunctionTestShell* shell_;
rgrover1 0:0b799af9d58e 204 };
rgrover1 0:0b799af9d58e 205
rgrover1 0:0b799af9d58e 206 //////////////////// ExecFunctionTestShell
rgrover1 0:0b799af9d58e 207
rgrover1 0:0b799af9d58e 208 class ExecFunctionTestShell: public UtestShell
rgrover1 0:0b799af9d58e 209 {
rgrover1 0:0b799af9d58e 210 public:
rgrover1 0:0b799af9d58e 211 void (*setup_)();
rgrover1 0:0b799af9d58e 212 void (*teardown_)();
rgrover1 0:0b799af9d58e 213 void (*testFunction_)();
rgrover1 0:0b799af9d58e 214
rgrover1 0:0b799af9d58e 215 ExecFunctionTestShell(void(*set)() = 0, void(*tear)() = 0) :
rgrover1 0:0b799af9d58e 216 UtestShell("Generic", "Generic", "Generic", 1), setup_(set), teardown_(
rgrover1 0:0b799af9d58e 217 tear), testFunction_(0)
rgrover1 0:0b799af9d58e 218 {
rgrover1 0:0b799af9d58e 219 }
rgrover1 0:0b799af9d58e 220 Utest* createTest() { return new ExecFunctionTest(this); }
rgrover1 0:0b799af9d58e 221 virtual ~ExecFunctionTestShell();
rgrover1 0:0b799af9d58e 222 };
rgrover1 0:0b799af9d58e 223
rgrover1 0:0b799af9d58e 224 //////////////////// CppUTestFailedException
rgrover1 0:0b799af9d58e 225
rgrover1 0:0b799af9d58e 226 class CppUTestFailedException
rgrover1 0:0b799af9d58e 227 {
rgrover1 0:0b799af9d58e 228 public:
rgrover1 0:0b799af9d58e 229 int dummy_;
rgrover1 0:0b799af9d58e 230 };
rgrover1 0:0b799af9d58e 231
rgrover1 0:0b799af9d58e 232 //////////////////// IgnoredTest
rgrover1 0:0b799af9d58e 233
rgrover1 0:0b799af9d58e 234 class IgnoredUtestShell : public UtestShell
rgrover1 0:0b799af9d58e 235 {
rgrover1 0:0b799af9d58e 236 public:
rgrover1 0:0b799af9d58e 237 IgnoredUtestShell();
rgrover1 0:0b799af9d58e 238 virtual ~IgnoredUtestShell();
rgrover1 0:0b799af9d58e 239 explicit IgnoredUtestShell(const char* groupName, const char* testName,
rgrover1 0:0b799af9d58e 240 const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 241 virtual const char* getProgressIndicator() const;
rgrover1 0:0b799af9d58e 242 protected: virtual SimpleString getMacroName() const _override;
rgrover1 0:0b799af9d58e 243 virtual void runOneTest(TestPlugin* plugin, TestResult& result) _override;
rgrover1 0:0b799af9d58e 244
rgrover1 0:0b799af9d58e 245 private:
rgrover1 0:0b799af9d58e 246
rgrover1 0:0b799af9d58e 247 IgnoredUtestShell(const IgnoredUtestShell&);
rgrover1 0:0b799af9d58e 248 IgnoredUtestShell& operator=(const IgnoredUtestShell&);
rgrover1 0:0b799af9d58e 249
rgrover1 0:0b799af9d58e 250 };
rgrover1 0:0b799af9d58e 251
rgrover1 0:0b799af9d58e 252 //////////////////// TestInstaller
rgrover1 0:0b799af9d58e 253
rgrover1 0:0b799af9d58e 254 class TestInstaller
rgrover1 0:0b799af9d58e 255 {
rgrover1 0:0b799af9d58e 256 public:
rgrover1 0:0b799af9d58e 257 explicit TestInstaller(UtestShell& shell, const char* groupName, const char* testName,
rgrover1 0:0b799af9d58e 258 const char* fileName, int lineNumber);
rgrover1 0:0b799af9d58e 259 virtual ~TestInstaller();
rgrover1 0:0b799af9d58e 260
rgrover1 0:0b799af9d58e 261 void unDo();
rgrover1 0:0b799af9d58e 262
rgrover1 0:0b799af9d58e 263 private:
rgrover1 0:0b799af9d58e 264
rgrover1 0:0b799af9d58e 265 TestInstaller(const TestInstaller&);
rgrover1 0:0b799af9d58e 266 TestInstaller& operator=(const TestInstaller&);
rgrover1 0:0b799af9d58e 267
rgrover1 0:0b799af9d58e 268 };
rgrover1 0:0b799af9d58e 269
rgrover1 0:0b799af9d58e 270 #endif