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:
rgrover1
Date:
Tue Jan 28 09:27:41 2014 +0000
Revision:
0:0b799af9d58e
Child:
1:4769360130ed
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 #include "CppUTest/TestHarness.h"
rgrover1 0:0b799af9d58e 29 #include "CppUTest/TestRegistry.h"
rgrover1 0:0b799af9d58e 30
rgrover1 0:0b799af9d58e 31 TestRegistry::TestRegistry() :
rgrover1 0:0b799af9d58e 32 tests_(&NullTestShell::instance()), firstPlugin_(NullTestPlugin::instance()), runInSeperateProcess_(false)
rgrover1 0:0b799af9d58e 33 {
rgrover1 0:0b799af9d58e 34 }
rgrover1 0:0b799af9d58e 35
rgrover1 0:0b799af9d58e 36 TestRegistry::~TestRegistry()
rgrover1 0:0b799af9d58e 37 {
rgrover1 0:0b799af9d58e 38 }
rgrover1 0:0b799af9d58e 39
rgrover1 0:0b799af9d58e 40 void TestRegistry::addTest(UtestShell *test)
rgrover1 0:0b799af9d58e 41 {
rgrover1 0:0b799af9d58e 42 tests_ = test->addTest(tests_);
rgrover1 0:0b799af9d58e 43 }
rgrover1 0:0b799af9d58e 44
rgrover1 0:0b799af9d58e 45 void TestRegistry::runAllTests(TestResult& result)
rgrover1 0:0b799af9d58e 46 {
rgrover1 0:0b799af9d58e 47 bool groupStart = true;
rgrover1 0:0b799af9d58e 48
rgrover1 0:0b799af9d58e 49 result.testsStarted();
rgrover1 0:0b799af9d58e 50 for (UtestShell *test = tests_; !test->isNull(); test = test->getNext()) {
rgrover1 0:0b799af9d58e 51 if (runInSeperateProcess_) test->setRunInSeperateProcess();
rgrover1 0:0b799af9d58e 52
rgrover1 0:0b799af9d58e 53 if (groupStart) {
rgrover1 0:0b799af9d58e 54 result.currentGroupStarted(test);
rgrover1 0:0b799af9d58e 55 groupStart = false;
rgrover1 0:0b799af9d58e 56 }
rgrover1 0:0b799af9d58e 57
rgrover1 0:0b799af9d58e 58 result.setProgressIndicator(test->getProgressIndicator());
rgrover1 0:0b799af9d58e 59 result.countTest();
rgrover1 0:0b799af9d58e 60 if (testShouldRun(test, result)) {
rgrover1 0:0b799af9d58e 61 result.currentTestStarted(test);
rgrover1 0:0b799af9d58e 62 test->runOneTest(firstPlugin_, result);
rgrover1 0:0b799af9d58e 63 result.currentTestEnded(test);
rgrover1 0:0b799af9d58e 64 }
rgrover1 0:0b799af9d58e 65
rgrover1 0:0b799af9d58e 66 if (endOfGroup(test)) {
rgrover1 0:0b799af9d58e 67 groupStart = true;
rgrover1 0:0b799af9d58e 68 result.currentGroupEnded(test);
rgrover1 0:0b799af9d58e 69 }
rgrover1 0:0b799af9d58e 70 }
rgrover1 0:0b799af9d58e 71 result.testsEnded();
rgrover1 0:0b799af9d58e 72 }
rgrover1 0:0b799af9d58e 73
rgrover1 0:0b799af9d58e 74 bool TestRegistry::endOfGroup(UtestShell* test)
rgrover1 0:0b799af9d58e 75 {
rgrover1 0:0b799af9d58e 76 return (test->isNull() || test->getGroup() != test->getNext()->getGroup());
rgrover1 0:0b799af9d58e 77 }
rgrover1 0:0b799af9d58e 78
rgrover1 0:0b799af9d58e 79 int TestRegistry::countTests()
rgrover1 0:0b799af9d58e 80 {
rgrover1 0:0b799af9d58e 81 return tests_->countTests();
rgrover1 0:0b799af9d58e 82 }
rgrover1 0:0b799af9d58e 83
rgrover1 0:0b799af9d58e 84 TestRegistry* TestRegistry::currentRegistry_ = 0;
rgrover1 0:0b799af9d58e 85
rgrover1 0:0b799af9d58e 86 TestRegistry* TestRegistry::getCurrentRegistry()
rgrover1 0:0b799af9d58e 87 {
rgrover1 0:0b799af9d58e 88 static TestRegistry registry;
rgrover1 0:0b799af9d58e 89 return (currentRegistry_ == 0) ? &registry : currentRegistry_;
rgrover1 0:0b799af9d58e 90 }
rgrover1 0:0b799af9d58e 91
rgrover1 0:0b799af9d58e 92 void TestRegistry::setCurrentRegistry(TestRegistry* registry)
rgrover1 0:0b799af9d58e 93 {
rgrover1 0:0b799af9d58e 94 currentRegistry_ = registry;
rgrover1 0:0b799af9d58e 95 }
rgrover1 0:0b799af9d58e 96
rgrover1 0:0b799af9d58e 97 void TestRegistry::unDoLastAddTest()
rgrover1 0:0b799af9d58e 98 {
rgrover1 0:0b799af9d58e 99 tests_ = tests_->getNext();
rgrover1 0:0b799af9d58e 100
rgrover1 0:0b799af9d58e 101 }
rgrover1 0:0b799af9d58e 102
rgrover1 0:0b799af9d58e 103 void TestRegistry::nameFilter(const TestFilter& f)
rgrover1 0:0b799af9d58e 104 {
rgrover1 0:0b799af9d58e 105 nameFilter_ = f;
rgrover1 0:0b799af9d58e 106 }
rgrover1 0:0b799af9d58e 107
rgrover1 0:0b799af9d58e 108 void TestRegistry::groupFilter(const TestFilter& f)
rgrover1 0:0b799af9d58e 109 {
rgrover1 0:0b799af9d58e 110 groupFilter_ = f;
rgrover1 0:0b799af9d58e 111 }
rgrover1 0:0b799af9d58e 112
rgrover1 0:0b799af9d58e 113 TestFilter TestRegistry::getGroupFilter()
rgrover1 0:0b799af9d58e 114 {
rgrover1 0:0b799af9d58e 115 return groupFilter_;
rgrover1 0:0b799af9d58e 116 }
rgrover1 0:0b799af9d58e 117
rgrover1 0:0b799af9d58e 118 TestFilter TestRegistry::getNameFilter()
rgrover1 0:0b799af9d58e 119 {
rgrover1 0:0b799af9d58e 120 return nameFilter_;
rgrover1 0:0b799af9d58e 121 }
rgrover1 0:0b799af9d58e 122
rgrover1 0:0b799af9d58e 123 void TestRegistry::setRunTestsInSeperateProcess()
rgrover1 0:0b799af9d58e 124 {
rgrover1 0:0b799af9d58e 125 runInSeperateProcess_ = true;
rgrover1 0:0b799af9d58e 126 }
rgrover1 0:0b799af9d58e 127
rgrover1 0:0b799af9d58e 128
rgrover1 0:0b799af9d58e 129 bool TestRegistry::testShouldRun(UtestShell* test, TestResult& result)
rgrover1 0:0b799af9d58e 130 {
rgrover1 0:0b799af9d58e 131 if (test->shouldRun(groupFilter_, nameFilter_)) return true;
rgrover1 0:0b799af9d58e 132 else {
rgrover1 0:0b799af9d58e 133 result.countFilteredOut();
rgrover1 0:0b799af9d58e 134 return false;
rgrover1 0:0b799af9d58e 135 }
rgrover1 0:0b799af9d58e 136 }
rgrover1 0:0b799af9d58e 137
rgrover1 0:0b799af9d58e 138 void TestRegistry::resetPlugins()
rgrover1 0:0b799af9d58e 139 {
rgrover1 0:0b799af9d58e 140 firstPlugin_ = NullTestPlugin::instance();
rgrover1 0:0b799af9d58e 141 }
rgrover1 0:0b799af9d58e 142
rgrover1 0:0b799af9d58e 143 void TestRegistry::installPlugin(TestPlugin* plugin)
rgrover1 0:0b799af9d58e 144 {
rgrover1 0:0b799af9d58e 145 firstPlugin_ = plugin->addPlugin(firstPlugin_);
rgrover1 0:0b799af9d58e 146 }
rgrover1 0:0b799af9d58e 147
rgrover1 0:0b799af9d58e 148 TestPlugin* TestRegistry::getFirstPlugin()
rgrover1 0:0b799af9d58e 149 {
rgrover1 0:0b799af9d58e 150 return firstPlugin_;
rgrover1 0:0b799af9d58e 151 }
rgrover1 0:0b799af9d58e 152
rgrover1 0:0b799af9d58e 153 TestPlugin* TestRegistry::getPluginByName(const SimpleString& name)
rgrover1 0:0b799af9d58e 154 {
rgrover1 0:0b799af9d58e 155 return firstPlugin_->getPluginByName(name);
rgrover1 0:0b799af9d58e 156 }
rgrover1 0:0b799af9d58e 157
rgrover1 0:0b799af9d58e 158 void TestRegistry::removePluginByName(const SimpleString& name)
rgrover1 0:0b799af9d58e 159 {
rgrover1 0:0b799af9d58e 160 if (firstPlugin_->removePluginByName(name) == firstPlugin_) firstPlugin_ = firstPlugin_->getNext();
rgrover1 0:0b799af9d58e 161 if (firstPlugin_->getName() == name) firstPlugin_ = firstPlugin_->getNext();
rgrover1 0:0b799af9d58e 162 firstPlugin_->removePluginByName(name);
rgrover1 0:0b799af9d58e 163 }
rgrover1 0:0b799af9d58e 164
rgrover1 0:0b799af9d58e 165 int TestRegistry::countPlugins()
rgrover1 0:0b799af9d58e 166 {
rgrover1 0:0b799af9d58e 167 int count = 0;
rgrover1 0:0b799af9d58e 168 for (TestPlugin* plugin = firstPlugin_; plugin != NullTestPlugin::instance(); plugin = plugin->getNext())
rgrover1 0:0b799af9d58e 169 count++;
rgrover1 0:0b799af9d58e 170 return count;
rgrover1 0:0b799af9d58e 171 }
rgrover1 0:0b799af9d58e 172
rgrover1 0:0b799af9d58e 173
rgrover1 0:0b799af9d58e 174 UtestShell* TestRegistry::getFirstTest()
rgrover1 0:0b799af9d58e 175 {
rgrover1 0:0b799af9d58e 176 return tests_;
rgrover1 0:0b799af9d58e 177 }
rgrover1 0:0b799af9d58e 178
rgrover1 0:0b799af9d58e 179 UtestShell* TestRegistry::getLastTest()
rgrover1 0:0b799af9d58e 180 {
rgrover1 0:0b799af9d58e 181 UtestShell* current = tests_;
rgrover1 0:0b799af9d58e 182 while (!current->getNext()->isNull())
rgrover1 0:0b799af9d58e 183 current = current->getNext();
rgrover1 0:0b799af9d58e 184 return current;
rgrover1 0:0b799af9d58e 185 }
rgrover1 0:0b799af9d58e 186
rgrover1 0:0b799af9d58e 187 UtestShell* TestRegistry::getTestWithNext(UtestShell* test)
rgrover1 0:0b799af9d58e 188 {
rgrover1 0:0b799af9d58e 189 UtestShell* current = tests_;
rgrover1 0:0b799af9d58e 190 while (!current->getNext()->isNull() && current->getNext() != test)
rgrover1 0:0b799af9d58e 191 current = current->getNext();
rgrover1 0:0b799af9d58e 192 return current;
rgrover1 0:0b799af9d58e 193 }
rgrover1 0:0b799af9d58e 194
rgrover1 0:0b799af9d58e 195 UtestShell* TestRegistry::findTestWithName(const SimpleString& name)
rgrover1 0:0b799af9d58e 196 {
rgrover1 0:0b799af9d58e 197 UtestShell* current = tests_;
rgrover1 0:0b799af9d58e 198 while (!current->isNull()) {
rgrover1 0:0b799af9d58e 199 if (current->getName() == name)
rgrover1 0:0b799af9d58e 200 return current;
rgrover1 0:0b799af9d58e 201 current = current->getNext();
rgrover1 0:0b799af9d58e 202 }
rgrover1 0:0b799af9d58e 203 return NULL;
rgrover1 0:0b799af9d58e 204 }
rgrover1 0:0b799af9d58e 205
rgrover1 0:0b799af9d58e 206 UtestShell* TestRegistry::findTestWithGroup(const SimpleString& group)
rgrover1 0:0b799af9d58e 207 {
rgrover1 0:0b799af9d58e 208 UtestShell* current = tests_;
rgrover1 0:0b799af9d58e 209 while (!current->isNull()) {
rgrover1 0:0b799af9d58e 210 if (current->getGroup() == group)
rgrover1 0:0b799af9d58e 211 return current;
rgrover1 0:0b799af9d58e 212 current = current->getNext();
rgrover1 0:0b799af9d58e 213 }
rgrover1 0:0b799af9d58e 214 return NULL;
rgrover1 0:0b799af9d58e 215 }
rgrover1 0:0b799af9d58e 216