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:
Tue Jun 17 15:52:54 2014 +0100
Revision:
1:4769360130ed
Parent:
0:0b799af9d58e
updating to the latest version of cppUtest; tested against nordic's m-kit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 1:4769360130ed 1 /*
Rohit Grover 1:4769360130ed 2 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
Rohit Grover 1:4769360130ed 3 * All rights reserved.
Rohit Grover 1:4769360130ed 4 *
Rohit Grover 1:4769360130ed 5 * Redistribution and use in source and binary forms, with or without
Rohit Grover 1:4769360130ed 6 * modification, are permitted provided that the following conditions are met:
Rohit Grover 1:4769360130ed 7 * * Redistributions of source code must retain the above copyright
Rohit Grover 1:4769360130ed 8 * notice, this list of conditions and the following disclaimer.
Rohit Grover 1:4769360130ed 9 * * Redistributions in binary form must reproduce the above copyright
Rohit Grover 1:4769360130ed 10 * notice, this list of conditions and the following disclaimer in the
Rohit Grover 1:4769360130ed 11 * documentation and/or other materials provided with the distribution.
Rohit Grover 1:4769360130ed 12 * * Neither the name of the <organization> nor the
Rohit Grover 1:4769360130ed 13 * names of its contributors may be used to endorse or promote products
Rohit Grover 1:4769360130ed 14 * derived from this software without specific prior written permission.
Rohit Grover 1:4769360130ed 15 *
Rohit Grover 1:4769360130ed 16 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
Rohit Grover 1:4769360130ed 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Rohit Grover 1:4769360130ed 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Rohit Grover 1:4769360130ed 19 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
Rohit Grover 1:4769360130ed 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Rohit Grover 1:4769360130ed 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Rohit Grover 1:4769360130ed 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Rohit Grover 1:4769360130ed 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Rohit Grover 1:4769360130ed 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Rohit Grover 1:4769360130ed 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Rohit Grover 1:4769360130ed 26 */
Rohit Grover 1:4769360130ed 27
Rohit Grover 1:4769360130ed 28 #include "CppUTest/TestHarness.h"
Rohit Grover 1:4769360130ed 29 #include "CppUTest/TestRegistry.h"
Rohit Grover 1:4769360130ed 30
Rohit Grover 1:4769360130ed 31 TestRegistry::TestRegistry() :
Rohit Grover 1:4769360130ed 32 tests_(&NullTestShell::instance()), firstPlugin_(NullTestPlugin::instance()), runInSeperateProcess_(false)
Rohit Grover 1:4769360130ed 33 {
Rohit Grover 1:4769360130ed 34 }
Rohit Grover 1:4769360130ed 35
Rohit Grover 1:4769360130ed 36 TestRegistry::~TestRegistry()
Rohit Grover 1:4769360130ed 37 {
Rohit Grover 1:4769360130ed 38 }
Rohit Grover 1:4769360130ed 39
Rohit Grover 1:4769360130ed 40 void TestRegistry::addTest(UtestShell *test)
Rohit Grover 1:4769360130ed 41 {
Rohit Grover 1:4769360130ed 42 tests_ = test->addTest(tests_);
Rohit Grover 1:4769360130ed 43 }
Rohit Grover 1:4769360130ed 44
Rohit Grover 1:4769360130ed 45 void TestRegistry::runAllTests(TestResult& result)
Rohit Grover 1:4769360130ed 46 {
Rohit Grover 1:4769360130ed 47 bool groupStart = true;
Rohit Grover 1:4769360130ed 48
Rohit Grover 1:4769360130ed 49 result.testsStarted();
Rohit Grover 1:4769360130ed 50 for (UtestShell *test = tests_; !test->isNull(); test = test->getNext()) {
Rohit Grover 1:4769360130ed 51 if (runInSeperateProcess_) test->setRunInSeperateProcess();
Rohit Grover 1:4769360130ed 52
Rohit Grover 1:4769360130ed 53 if (groupStart) {
Rohit Grover 1:4769360130ed 54 result.currentGroupStarted(test);
Rohit Grover 1:4769360130ed 55 groupStart = false;
Rohit Grover 1:4769360130ed 56 }
Rohit Grover 1:4769360130ed 57
Rohit Grover 1:4769360130ed 58 result.setProgressIndicator(test->getProgressIndicator());
Rohit Grover 1:4769360130ed 59 result.countTest();
Rohit Grover 1:4769360130ed 60 if (testShouldRun(test, result)) {
Rohit Grover 1:4769360130ed 61 result.currentTestStarted(test);
Rohit Grover 1:4769360130ed 62 test->runOneTest(firstPlugin_, result);
Rohit Grover 1:4769360130ed 63 result.currentTestEnded(test);
Rohit Grover 1:4769360130ed 64 }
Rohit Grover 1:4769360130ed 65
Rohit Grover 1:4769360130ed 66 if (endOfGroup(test)) {
Rohit Grover 1:4769360130ed 67 groupStart = true;
Rohit Grover 1:4769360130ed 68 result.currentGroupEnded(test);
Rohit Grover 1:4769360130ed 69 }
Rohit Grover 1:4769360130ed 70 }
Rohit Grover 1:4769360130ed 71 result.testsEnded();
Rohit Grover 1:4769360130ed 72 }
Rohit Grover 1:4769360130ed 73
Rohit Grover 1:4769360130ed 74 bool TestRegistry::endOfGroup(UtestShell* test)
Rohit Grover 1:4769360130ed 75 {
Rohit Grover 1:4769360130ed 76 return (test->isNull() || test->getGroup() != test->getNext()->getGroup());
Rohit Grover 1:4769360130ed 77 }
Rohit Grover 1:4769360130ed 78
Rohit Grover 1:4769360130ed 79 int TestRegistry::countTests()
Rohit Grover 1:4769360130ed 80 {
Rohit Grover 1:4769360130ed 81 return tests_->countTests();
Rohit Grover 1:4769360130ed 82 }
Rohit Grover 1:4769360130ed 83
Rohit Grover 1:4769360130ed 84 TestRegistry* TestRegistry::currentRegistry_ = 0;
Rohit Grover 1:4769360130ed 85
Rohit Grover 1:4769360130ed 86 TestRegistry* TestRegistry::getCurrentRegistry()
Rohit Grover 1:4769360130ed 87 {
Rohit Grover 1:4769360130ed 88 static TestRegistry registry;
Rohit Grover 1:4769360130ed 89 return (currentRegistry_ == 0) ? &registry : currentRegistry_;
Rohit Grover 1:4769360130ed 90 }
Rohit Grover 1:4769360130ed 91
Rohit Grover 1:4769360130ed 92 void TestRegistry::setCurrentRegistry(TestRegistry* registry)
Rohit Grover 1:4769360130ed 93 {
Rohit Grover 1:4769360130ed 94 currentRegistry_ = registry;
Rohit Grover 1:4769360130ed 95 }
Rohit Grover 1:4769360130ed 96
Rohit Grover 1:4769360130ed 97 void TestRegistry::unDoLastAddTest()
Rohit Grover 1:4769360130ed 98 {
Rohit Grover 1:4769360130ed 99 tests_ = tests_->getNext();
Rohit Grover 1:4769360130ed 100
Rohit Grover 1:4769360130ed 101 }
Rohit Grover 1:4769360130ed 102
Rohit Grover 1:4769360130ed 103 void TestRegistry::nameFilter(const TestFilter& f)
Rohit Grover 1:4769360130ed 104 {
Rohit Grover 1:4769360130ed 105 nameFilter_ = f;
Rohit Grover 1:4769360130ed 106 }
Rohit Grover 1:4769360130ed 107
Rohit Grover 1:4769360130ed 108 void TestRegistry::groupFilter(const TestFilter& f)
Rohit Grover 1:4769360130ed 109 {
Rohit Grover 1:4769360130ed 110 groupFilter_ = f;
Rohit Grover 1:4769360130ed 111 }
Rohit Grover 1:4769360130ed 112
Rohit Grover 1:4769360130ed 113 TestFilter TestRegistry::getGroupFilter()
Rohit Grover 1:4769360130ed 114 {
Rohit Grover 1:4769360130ed 115 return groupFilter_;
Rohit Grover 1:4769360130ed 116 }
Rohit Grover 1:4769360130ed 117
Rohit Grover 1:4769360130ed 118 TestFilter TestRegistry::getNameFilter()
Rohit Grover 1:4769360130ed 119 {
Rohit Grover 1:4769360130ed 120 return nameFilter_;
Rohit Grover 1:4769360130ed 121 }
Rohit Grover 1:4769360130ed 122
Rohit Grover 1:4769360130ed 123 void TestRegistry::setRunTestsInSeperateProcess()
Rohit Grover 1:4769360130ed 124 {
Rohit Grover 1:4769360130ed 125 runInSeperateProcess_ = true;
Rohit Grover 1:4769360130ed 126 }
Rohit Grover 1:4769360130ed 127
Rohit Grover 1:4769360130ed 128
Rohit Grover 1:4769360130ed 129 bool TestRegistry::testShouldRun(UtestShell* test, TestResult& result)
Rohit Grover 1:4769360130ed 130 {
Rohit Grover 1:4769360130ed 131 if (test->shouldRun(groupFilter_, nameFilter_)) return true;
Rohit Grover 1:4769360130ed 132 else {
Rohit Grover 1:4769360130ed 133 result.countFilteredOut();
Rohit Grover 1:4769360130ed 134 return false;
Rohit Grover 1:4769360130ed 135 }
Rohit Grover 1:4769360130ed 136 }
Rohit Grover 1:4769360130ed 137
Rohit Grover 1:4769360130ed 138 void TestRegistry::resetPlugins()
Rohit Grover 1:4769360130ed 139 {
Rohit Grover 1:4769360130ed 140 firstPlugin_ = NullTestPlugin::instance();
Rohit Grover 1:4769360130ed 141 }
Rohit Grover 1:4769360130ed 142
Rohit Grover 1:4769360130ed 143 void TestRegistry::installPlugin(TestPlugin* plugin)
Rohit Grover 1:4769360130ed 144 {
Rohit Grover 1:4769360130ed 145 firstPlugin_ = plugin->addPlugin(firstPlugin_);
Rohit Grover 1:4769360130ed 146 }
Rohit Grover 1:4769360130ed 147
Rohit Grover 1:4769360130ed 148 TestPlugin* TestRegistry::getFirstPlugin()
Rohit Grover 1:4769360130ed 149 {
Rohit Grover 1:4769360130ed 150 return firstPlugin_;
Rohit Grover 1:4769360130ed 151 }
Rohit Grover 1:4769360130ed 152
Rohit Grover 1:4769360130ed 153 TestPlugin* TestRegistry::getPluginByName(const SimpleString& name)
Rohit Grover 1:4769360130ed 154 {
Rohit Grover 1:4769360130ed 155 return firstPlugin_->getPluginByName(name);
Rohit Grover 1:4769360130ed 156 }
Rohit Grover 1:4769360130ed 157
Rohit Grover 1:4769360130ed 158 void TestRegistry::removePluginByName(const SimpleString& name)
Rohit Grover 1:4769360130ed 159 {
Rohit Grover 1:4769360130ed 160 if (firstPlugin_->removePluginByName(name) == firstPlugin_) firstPlugin_ = firstPlugin_->getNext();
Rohit Grover 1:4769360130ed 161 if (firstPlugin_->getName() == name) firstPlugin_ = firstPlugin_->getNext();
Rohit Grover 1:4769360130ed 162 firstPlugin_->removePluginByName(name);
Rohit Grover 1:4769360130ed 163 }
Rohit Grover 1:4769360130ed 164
Rohit Grover 1:4769360130ed 165 int TestRegistry::countPlugins()
Rohit Grover 1:4769360130ed 166 {
Rohit Grover 1:4769360130ed 167 int count = 0;
Rohit Grover 1:4769360130ed 168 for (TestPlugin* plugin = firstPlugin_; plugin != NullTestPlugin::instance(); plugin = plugin->getNext())
Rohit Grover 1:4769360130ed 169 count++;
Rohit Grover 1:4769360130ed 170 return count;
Rohit Grover 1:4769360130ed 171 }
Rohit Grover 1:4769360130ed 172
Rohit Grover 1:4769360130ed 173
Rohit Grover 1:4769360130ed 174 UtestShell* TestRegistry::getFirstTest()
Rohit Grover 1:4769360130ed 175 {
Rohit Grover 1:4769360130ed 176 return tests_;
Rohit Grover 1:4769360130ed 177 }
Rohit Grover 1:4769360130ed 178
Rohit Grover 1:4769360130ed 179 UtestShell* TestRegistry::getLastTest()
Rohit Grover 1:4769360130ed 180 {
Rohit Grover 1:4769360130ed 181 UtestShell* current = tests_;
Rohit Grover 1:4769360130ed 182 while (!current->getNext()->isNull())
Rohit Grover 1:4769360130ed 183 current = current->getNext();
Rohit Grover 1:4769360130ed 184 return current;
Rohit Grover 1:4769360130ed 185 }
Rohit Grover 1:4769360130ed 186
Rohit Grover 1:4769360130ed 187 UtestShell* TestRegistry::getTestWithNext(UtestShell* test)
Rohit Grover 1:4769360130ed 188 {
Rohit Grover 1:4769360130ed 189 UtestShell* current = tests_;
Rohit Grover 1:4769360130ed 190 while (!current->getNext()->isNull() && current->getNext() != test)
Rohit Grover 1:4769360130ed 191 current = current->getNext();
Rohit Grover 1:4769360130ed 192 return current;
Rohit Grover 1:4769360130ed 193 }
Rohit Grover 1:4769360130ed 194
Rohit Grover 1:4769360130ed 195 UtestShell* TestRegistry::findTestWithName(const SimpleString& name)
Rohit Grover 1:4769360130ed 196 {
Rohit Grover 1:4769360130ed 197 UtestShell* current = tests_;
Rohit Grover 1:4769360130ed 198 while (!current->isNull()) {
Rohit Grover 1:4769360130ed 199 if (current->getName() == name)
Rohit Grover 1:4769360130ed 200 return current;
Rohit Grover 1:4769360130ed 201 current = current->getNext();
Rohit Grover 1:4769360130ed 202 }
Rohit Grover 1:4769360130ed 203 return NULL;
Rohit Grover 1:4769360130ed 204 }
Rohit Grover 1:4769360130ed 205
Rohit Grover 1:4769360130ed 206 UtestShell* TestRegistry::findTestWithGroup(const SimpleString& group)
Rohit Grover 1:4769360130ed 207 {
Rohit Grover 1:4769360130ed 208 UtestShell* current = tests_;
Rohit Grover 1:4769360130ed 209 while (!current->isNull()) {
Rohit Grover 1:4769360130ed 210 if (current->getGroup() == group)
Rohit Grover 1:4769360130ed 211 return current;
Rohit Grover 1:4769360130ed 212 current = current->getNext();
Rohit Grover 1:4769360130ed 213 }
Rohit Grover 1:4769360130ed 214 return NULL;
Rohit Grover 1:4769360130ed 215 }
Rohit Grover 1:4769360130ed 216