提交 9a393a28 编写于 作者: M Mark VanderVoord

Merge pull request #50 from uozuAho/master

Added more examples
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
UNITY_ROOT=../..
C_COMPILER=gcc
TARGET_BASE1=test1
TARGET_BASE2=test2
ifeq ($(OS),Windows_NT)
TARGET_EXTENSION=.exe
else
TARGET_EXTENSION=.out
endif
TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION)
TARGET2 = $(TARGET_BASE2)$(TARGET_EXTENSION)
SRC_FILES1=$(UNITY_ROOT)/src/unity.c src/ProductionCode.c test/TestProductionCode.c test/test_runners/TestProductionCode_Runner.c
SRC_FILES2=$(UNITY_ROOT)/src/unity.c src/ProductionCode2.c test/TestProductionCode2.c test/test_runners/TestProductionCode2_Runner.c
INC_DIRS=-Isrc -I$(UNITY_ROOT)/src
SYMBOLS=-DTEST
ifeq ($(OS),Windows_NT)
CLEANUP = del /F /Q $(TARGET1) && del /F /Q $(TARGET2)
else
CLEANUP = rm -f build/*.o ; rm -f $(TARGET1) ; rm -f $(TARGET2)
endif
all: clean default
default:
# ruby auto/generate_test_runner.rb test/TestProductionCode.c test/test_runners/TestProductionCode_Runner.c
# ruby auto/generate_test_runner.rb test/TestProductionCode2.c test/test_runners/TestProductionCode2_Runner.c
$(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1)
$(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES2) -o $(TARGET2)
./$(TARGET1)
./$(TARGET2)
clean:
$(CLEANUP)
Example 1
=========
Close to the simplest possible example of Unity, using only basic features.
Run make to build & run the example tests.
\ No newline at end of file
#include "ProductionCode.h" #include "ProductionCode.h"
int Counter = 0; int Counter = 0;
int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; //some obnoxious array to search that is 1-based indexing instead of 0. int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; //some obnoxious array to search that is 1-based indexing instead of 0.
// This function is supposed to search through NumbersToFind and find a particular number. // This function is supposed to search through NumbersToFind and find a particular number.
// If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since // If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since
// NumbersToFind is indexed from 1. Unfortunately it's broken // NumbersToFind is indexed from 1. Unfortunately it's broken
// (and should therefore be caught by our tests) // (and should therefore be caught by our tests)
int FindFunction_WhichIsBroken(int NumberToFind) int FindFunction_WhichIsBroken(int NumberToFind)
{ {
int i = 0; int i = 0;
while (i <= 8) //Notice I should have been in braces while (i <= 8) //Notice I should have been in braces
i++; i++;
if (NumbersToFind[i] == NumberToFind) //Yikes! I'm getting run after the loop finishes instead of during it! if (NumbersToFind[i] == NumberToFind) //Yikes! I'm getting run after the loop finishes instead of during it!
return i; return i;
return 0; return 0;
} }
int FunctionWhichReturnsLocalVariable(void) int FunctionWhichReturnsLocalVariable(void)
{ {
return Counter; return Counter;
} }
int FindFunction_WhichIsBroken(int NumberToFind); int FindFunction_WhichIsBroken(int NumberToFind);
int FunctionWhichReturnsLocalVariable(void); int FunctionWhichReturnsLocalVariable(void);
#include "ProductionCode2.h" #include "ProductionCode2.h"
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction) char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction)
{ {
//Since There Are No Tests Yet, This Function Could Be Empty For All We Know. //Since There Are No Tests Yet, This Function Could Be Empty For All We Know.
// Which isn't terribly useful... but at least we put in a TEST_IGNORE so we won't forget // Which isn't terribly useful... but at least we put in a TEST_IGNORE so we won't forget
return (char*)0; return (char*)0;
} }
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction); char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction);
#include "ProductionCode.h" #include "ProductionCode.h"
#include "unity.h" #include "unity.h"
//sometimes you may want to get at local data in a module. //sometimes you may want to get at local data in a module.
//for example: If you plan to pass by reference, this could be useful //for example: If you plan to pass by reference, this could be useful
//however, it should often be avoided //however, it should often be avoided
extern int Counter; extern int Counter;
void setUp(void) void setUp(void)
{ {
//This is run before EACH TEST //This is run before EACH TEST
Counter = 0x5a5a; Counter = 0x5a5a;
} }
void tearDown(void) void tearDown(void)
{ {
} }
void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void) void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void)
{ {
//All of these should pass //All of these should pass
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(1)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(1));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(999)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(999));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(-1)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(-1));
} }
void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void) void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void)
{ {
// You should see this line fail in your test summary // You should see this line fail in your test summary
TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34)); TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34));
// Notice the rest of these didn't get a chance to run because the line above failed. // Notice the rest of these didn't get a chance to run because the line above failed.
// Unit tests abort each test function on the first sign of trouble. // Unit tests abort each test function on the first sign of trouble.
// Then NEXT test function runs as normal. // Then NEXT test function runs as normal.
TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888)); TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888));
} }
void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void) void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void)
{ {
//This should be true because setUp set this up for us before this test //This should be true because setUp set this up for us before this test
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
//This should be true because we can still change our answer //This should be true because we can still change our answer
Counter = 0x1234; Counter = 0x1234;
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
} }
void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void) void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void)
{ {
//This should be true again because setup was rerun before this test (and after we changed it to 0x1234) //This should be true again because setup was rerun before this test (and after we changed it to 0x1234)
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
} }
void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void) void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void)
{ {
//Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell //Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell
// you what actually happened...which in this case was a failure to setup the initial condition. // you what actually happened...which in this case was a failure to setup the initial condition.
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
} }
#include "ProductionCode2.h" #include "ProductionCode2.h"
#include "unity.h" #include "unity.h"
/* These should be ignored because they are commented out in various ways: /* These should be ignored because they are commented out in various ways:
#include "whatever.h" #include "whatever.h"
*/ */
//#include "somethingelse.h" //#include "somethingelse.h"
void setUp(void) void setUp(void)
{ {
} }
void tearDown(void) void tearDown(void)
{ {
} }
void test_IgnoredTest(void) void test_IgnoredTest(void)
{ {
TEST_IGNORE_MESSAGE("This Test Was Ignored On Purpose"); TEST_IGNORE_MESSAGE("This Test Was Ignored On Purpose");
} }
void test_AnotherIgnoredTest(void) void test_AnotherIgnoredTest(void)
{ {
TEST_IGNORE_MESSAGE("These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet"); TEST_IGNORE_MESSAGE("These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet");
} }
void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void) void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void)
{ {
TEST_IGNORE(); //Like This TEST_IGNORE(); //Like This
} }
/* AUTOGENERATED FILE. DO NOT EDIT. */ /* AUTOGENERATED FILE. DO NOT EDIT. */
#include "unity.h" #include "unity.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
char MessageBuffer[50]; char MessageBuffer[50];
extern void setUp(void); extern void setUp(void);
extern void tearDown(void); extern void tearDown(void);
extern void test_IgnoredTest(void); extern void test_IgnoredTest(void);
extern void test_AnotherIgnoredTest(void); extern void test_AnotherIgnoredTest(void);
extern void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void); extern void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void);
static void runTest(UnityTestFunction test) static void runTest(UnityTestFunction test)
{ {
if (TEST_PROTECT()) if (TEST_PROTECT())
{ {
setUp(); setUp();
test(); test();
} }
if (TEST_PROTECT() && !TEST_IS_IGNORED) if (TEST_PROTECT() && !TEST_IS_IGNORED)
{ {
tearDown(); tearDown();
} }
} }
void resetTest() void resetTest()
{ {
tearDown(); tearDown();
setUp(); setUp();
} }
int main(void) int main(void)
{ {
Unity.TestFile = "test/TestProductionCode2.c"; Unity.TestFile = "test/TestProductionCode2.c";
UnityBegin(); UnityBegin();
// RUN_TEST calls runTest // RUN_TEST calls runTest
RUN_TEST(test_IgnoredTest, 13); RUN_TEST(test_IgnoredTest, 13);
RUN_TEST(test_AnotherIgnoredTest, 18); RUN_TEST(test_AnotherIgnoredTest, 18);
RUN_TEST(test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented, 23); RUN_TEST(test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented, 23);
UnityEnd(); UnityEnd();
return 0; return 0;
} }
/* AUTOGENERATED FILE. DO NOT EDIT. */ /* AUTOGENERATED FILE. DO NOT EDIT. */
#include "unity.h" #include "unity.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
char MessageBuffer[50]; char MessageBuffer[50];
extern void setUp(void); extern void setUp(void);
extern void tearDown(void); extern void tearDown(void);
extern void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void); extern void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void);
extern void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void); extern void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void); extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void); extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void); extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void);
static void runTest(UnityTestFunction test) static void runTest(UnityTestFunction test)
{ {
if (TEST_PROTECT()) if (TEST_PROTECT())
{ {
setUp(); setUp();
test(); test();
} }
if (TEST_PROTECT() && !TEST_IS_IGNORED) if (TEST_PROTECT() && !TEST_IS_IGNORED)
{ {
tearDown(); tearDown();
} }
} }
void resetTest() void resetTest()
{ {
tearDown(); tearDown();
setUp(); setUp();
} }
int main(void) int main(void)
{ {
Unity.TestFile = "test/TestProductionCode.c"; Unity.TestFile = "test/TestProductionCode.c";
UnityBegin(); UnityBegin();
// RUN_TEST calls runTest // RUN_TEST calls runTest
RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode, 20); RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode, 20);
RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken, 30); RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken, 30);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue, 41); RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue, 41);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain, 51); RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain, 51);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed, 57); RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed, 57);
UnityEnd(); UnityEnd();
return 0; return 0;
} }
# ==========================================
# Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details]
# ==========================================
UNITY_ROOT=../..
C_COMPILER=gcc
TARGET_BASE1=all_tests
ifeq ($(OS),Windows_NT)
TARGET_EXTENSION=.exe
else
TARGET_EXTENSION=.out
endif
TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION)
SRC_FILES1=\
$(UNITY_ROOT)/src/unity.c \
$(UNITY_ROOT)/extras/fixture/src/unity_fixture.c \
src/ProductionCode.c \
src/ProductionCode2.c \
test/TestProductionCode.c \
test/TestProductionCode2.c \
test/test_runners/TestProductionCode_Runner.c \
test/test_runners/TestProductionCode2_Runner.c \
test/test_runners/all_tests.c
INC_DIRS=-Isrc -I$(UNITY_ROOT)/src -I$(UNITY_ROOT)/extras/fixture/src
SYMBOLS=
ifeq ($(OS),Windows_NT)
CLEANUP = del /F /Q $(TARGET1)
else
CLEANUP = rm -f build/*.o ; rm -f $(TARGET1)
endif
all: clean default
default:
# ruby auto/generate_test_runner.rb test/TestProductionCode.c test/test_runners/TestProductionCode_Runner.c
# ruby auto/generate_test_runner.rb test/TestProductionCode2.c test/test_runners/TestProductionCode2_Runner.c
$(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1)
./$(TARGET1)
clean:
$(CLEANUP)
Example 2
=========
Same as the first example, but now using Unity's test fixture to group tests
together. Using the test fixture also makes writing test runners much easier.
\ No newline at end of file
#include "ProductionCode.h"
int Counter = 0;
int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; //some obnoxious array to search that is 1-based indexing instead of 0.
// This function is supposed to search through NumbersToFind and find a particular number.
// If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since
// NumbersToFind is indexed from 1. Unfortunately it's broken
// (and should therefore be caught by our tests)
int FindFunction_WhichIsBroken(int NumberToFind)
{
int i = 0;
while (i <= 8) //Notice I should have been in braces
i++;
if (NumbersToFind[i] == NumberToFind) //Yikes! I'm getting run after the loop finishes instead of during it!
return i;
return 0;
}
int FunctionWhichReturnsLocalVariable(void)
{
return Counter;
}
int FindFunction_WhichIsBroken(int NumberToFind);
int FunctionWhichReturnsLocalVariable(void);
#include "ProductionCode2.h"
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction)
{
//Since There Are No Tests Yet, This Function Could Be Empty For All We Know.
// Which isn't terribly useful... but at least we put in a TEST_IGNORE so we won't forget
return (char*)0;
}
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction);
#include "ProductionCode.h"
#include "unity.h"
#include "unity_fixture.h"
TEST_GROUP(ProductionCode);
//sometimes you may want to get at local data in a module.
//for example: If you plan to pass by reference, this could be useful
//however, it should often be avoided
extern int Counter;
TEST_SETUP(ProductionCode)
{
//This is run before EACH TEST
Counter = 0x5a5a;
}
TEST_TEAR_DOWN(ProductionCode)
{
}
TEST(ProductionCode, FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode)
{
//All of these should pass
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(1));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(999));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(-1));
}
TEST(ProductionCode, FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken)
{
// You should see this line fail in your test summary
TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34));
// Notice the rest of these didn't get a chance to run because the line above failed.
// Unit tests abort each test function on the first sign of trouble.
// Then NEXT test function runs as normal.
TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888));
}
TEST(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue)
{
//This should be true because setUp set this up for us before this test
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
//This should be true because we can still change our answer
Counter = 0x1234;
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
}
TEST(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain)
{
//This should be true again because setup was rerun before this test (and after we changed it to 0x1234)
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
}
TEST(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed)
{
//Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell
// you what actually happened...which in this case was a failure to setup the initial condition.
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
}
#include "ProductionCode2.h"
#include "unity.h"
#include "unity_fixture.h"
TEST_GROUP(ProductionCode2);
/* These should be ignored because they are commented out in various ways:
#include "whatever.h"
*/
//#include "somethingelse.h"
TEST_SETUP(ProductionCode2)
{
}
TEST_TEAR_DOWN(ProductionCode2)
{
}
TEST(ProductionCode2, IgnoredTest)
{
TEST_IGNORE_MESSAGE("This Test Was Ignored On Purpose");
}
TEST(ProductionCode2, AnotherIgnoredTest)
{
TEST_IGNORE_MESSAGE("These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet");
}
TEST(ProductionCode2, ThisFunctionHasNotBeenTested_NeedsToBeImplemented)
{
TEST_IGNORE(); //Like This
}
#include "unity.h"
#include "unity_fixture.h"
TEST_GROUP_RUNNER(ProductionCode2)
{
RUN_TEST_CASE(ProductionCode2, IgnoredTest);
RUN_TEST_CASE(ProductionCode2, AnotherIgnoredTest);
RUN_TEST_CASE(ProductionCode2, ThisFunctionHasNotBeenTested_NeedsToBeImplemented);
}
\ No newline at end of file
#include "unity.h"
#include "unity_fixture.h"
TEST_GROUP_RUNNER(ProductionCode)
{
RUN_TEST_CASE(ProductionCode, FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode);
RUN_TEST_CASE(ProductionCode, FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken);
RUN_TEST_CASE(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue);
RUN_TEST_CASE(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain);
RUN_TEST_CASE(ProductionCode, FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed);
}
\ No newline at end of file
#include "unity_fixture.h"
static void RunAllTests(void)
{
RUN_TEST_GROUP(ProductionCode);
RUN_TEST_GROUP(ProductionCode2);
}
int main(int argc, char * argv[])
{
return UnityMain(argc, argv, RunAllTests);
}
\ No newline at end of file
#include "unity.h" #include "unity.h"
#include "UnityHelper.h" #include "UnityHelper.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
void AssertEqualExampleStruct(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line) void AssertEqualExampleStruct(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line)
{ {
UNITY_TEST_ASSERT_EQUAL_INT(expected.x, actual.x, line, "Example Struct Failed For Field x"); UNITY_TEST_ASSERT_EQUAL_INT(expected.x, actual.x, line, "Example Struct Failed For Field x");
UNITY_TEST_ASSERT_EQUAL_INT(expected.y, actual.y, line, "Example Struct Failed For Field y"); UNITY_TEST_ASSERT_EQUAL_INT(expected.y, actual.y, line, "Example Struct Failed For Field y");
} }
#ifndef _TESTHELPER_H #ifndef _TESTHELPER_H
#define _TESTHELPER_H #define _TESTHELPER_H
#include "Types.h" #include "Types.h"
void AssertEqualExampleStruct(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line); void AssertEqualExampleStruct(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line);
#define UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, line, message) AssertEqualExampleStruct(expected, actual, line); #define UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, line, message) AssertEqualExampleStruct(expected, actual, line);
#define TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual) UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, __LINE__, NULL); #define TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual) UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, __LINE__, NULL);
#endif // _TESTHELPER_H #endif // _TESTHELPER_H
# ========================================== # ==========================================
# Unity Project - A Test Framework for C # Unity Project - A Test Framework for C
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams # Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
# [Released under MIT License. Please refer to license.txt for details] # [Released under MIT License. Please refer to license.txt for details]
# ========================================== # ==========================================
C_COMPILER=gcc UNITY_ROOT=../..
TARGET_BASE1=test1 C_COMPILER=gcc
TARGET_BASE2=test2 TARGET_BASE1=test1
ifeq ($(OS),Windows_NT) TARGET_BASE2=test2
TARGET_EXTENSION=.exe ifeq ($(OS),Windows_NT)
else TARGET_EXTENSION=.exe
TARGET_EXTENSION=.out else
endif TARGET_EXTENSION=.out
TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION) endif
TARGET2 = $(TARGET_BASE2)$(TARGET_EXTENSION) TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION)
SRC_FILES1=../src/unity.c src/ProductionCode.c test/TestProductionCode.c test/no_ruby/TestProductionCode_Runner.c TARGET2 = $(TARGET_BASE2)$(TARGET_EXTENSION)
SRC_FILES2=../src/unity.c src/ProductionCode2.c test/TestProductionCode2.c test/no_ruby/TestProductionCode2_Runner.c SRC_FILES1=$(UNITY_ROOT)/src/unity.c src/ProductionCode.c test/TestProductionCode.c test/no_ruby/TestProductionCode_Runner.c
INC_DIRS=-Isrc -I../src SRC_FILES2=$(UNITY_ROOT)/src/unity.c src/ProductionCode2.c test/TestProductionCode2.c test/no_ruby/TestProductionCode2_Runner.c
SYMBOLS=-DTEST INC_DIRS=-Isrc -I$(UNITY_ROOT)/src
SYMBOLS=-DTEST
ifeq ($(OSTYPE),cygwin)
CLEANUP = rm -f build/*.o ; rm -f $(TARGET) ; mkdir -p build ifeq ($(OS),Windows_NT)
else ifeq ($(OS),Windows_NT) CLEANUP = del /F /Q $(TARGET1) && del /F /Q $(TARGET2)
CLEANUP = del /F /Q build\* && del /F /Q $(TARGET1) && del /F /Q $(TARGET2) else
else CLEANUP = rm -f build/*.o ; rm -f $(TARGET1) ; rm -f $(TARGET2)
CLEANUP = rm -f build/*.o ; rm -f $(TARGET1) ; rm -f $(TARGET2) endif
endif
all: clean default
all: clean default
default:
default: # ruby auto/generate_test_runner.rb test/TestProductionCode.c test/no_ruby/TestProductionCode_Runner.c
# ruby auto/generate_test_runner.rb test/TestProductionCode.c test/no_ruby/TestProductionCode_Runner.c # ruby auto/generate_test_runner.rb test/TestProductionCode2.c test/no_ruby/TestProductionCode2_Runner.c
# ruby auto/generate_test_runner.rb test/TestProductionCode2.c test/no_ruby/TestProductionCode2_Runner.c $(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1)
$(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1) $(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES2) -o $(TARGET2)
$(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES2) -o $(TARGET2) ./$(TARGET1)
./$(TARGET1) ./$(TARGET2)
./$(TARGET2)
clean:
clean: $(CLEANUP)
$(CLEANUP)
HERE = File.expand_path(File.dirname(__FILE__)) + '/' HERE = File.expand_path(File.dirname(__FILE__)) + '/'
UNITY_ROOT = File.expand_path(File.dirname(__FILE__)) + '/../..'
require 'rake'
require 'rake/clean' require 'rake'
require 'rake/testtask' require 'rake/clean'
require HERE+'rakefile_helper' require 'rake/testtask'
require HERE+'rakefile_helper'
TEMP_DIRS = [
File.join(HERE, 'build') TEMP_DIRS = [
] File.join(HERE, 'build')
]
TEMP_DIRS.each do |dir|
directory(dir) TEMP_DIRS.each do |dir|
CLOBBER.include(dir) directory(dir)
end CLOBBER.include(dir)
end
task :prepare_for_tests => TEMP_DIRS
task :prepare_for_tests => TEMP_DIRS
include RakefileHelpers
include RakefileHelpers
# Load default configuration, for now
DEFAULT_CONFIG_FILE = 'gcc_32.yml' # Load default configuration, for now
configure_toolchain(DEFAULT_CONFIG_FILE) DEFAULT_CONFIG_FILE = 'target_gcc_32.yml'
configure_toolchain(DEFAULT_CONFIG_FILE)
task :unit => [:prepare_for_tests] do
run_tests get_unit_test_files task :unit => [:prepare_for_tests] do
end run_tests get_unit_test_files
end
desc "Generate test summary"
task :summary do desc "Generate test summary"
report_summary task :summary do
end report_summary
end
desc "Build and test Unity"
task :all => [:clean, :unit, :summary] desc "Build and test Unity"
task :default => [:clobber, :all] task :all => [:clean, :unit, :summary]
task :ci => [:default] task :default => [:clobber, :all]
task :cruise => [:default] task :ci => [:default]
task :cruise => [:default]
desc "Load configuration"
task :config, :config_file do |t, args| desc "Load configuration"
configure_toolchain(args[:config_file]) task :config, :config_file do |t, args|
end configure_toolchain(args[:config_file])
end
require 'yaml' require 'yaml'
require 'fileutils' require 'fileutils'
require HERE+'../auto/unity_test_summary' require UNITY_ROOT+'/auto/unity_test_summary'
require HERE+'../auto/generate_test_runner' require UNITY_ROOT+'/auto/generate_test_runner'
require HERE+'../auto/colour_reporter' require UNITY_ROOT+'/auto/colour_reporter'
module RakefileHelpers module RakefileHelpers
C_EXTENSION = '.c' C_EXTENSION = '.c'
def load_configuration(config_file) def load_configuration(config_file)
$cfg_file = "../targets/#{config_file}" $cfg_file = config_file
$cfg = YAML.load(File.read($cfg_file)) $cfg = YAML.load(File.read($cfg_file))
end end
def configure_clean def configure_clean
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil? CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil?
end end
def configure_toolchain(config_file=DEFAULT_CONFIG_FILE) def configure_toolchain(config_file=DEFAULT_CONFIG_FILE)
config_file += '.yml' unless config_file =~ /\.yml$/ config_file += '.yml' unless config_file =~ /\.yml$/
load_configuration('../targets/'+config_file) load_configuration(config_file)
configure_clean configure_clean
end end
def get_unit_test_files def get_unit_test_files
path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION
path.gsub!(/\\/, '/') path.gsub!(/\\/, '/')
FileList.new(path) FileList.new(path)
end end
def get_local_include_dirs def get_local_include_dirs
include_dirs = $cfg['compiler']['includes']['items'].dup include_dirs = $cfg['compiler']['includes']['items'].dup
include_dirs.delete_if {|dir| dir.is_a?(Array)} include_dirs.delete_if {|dir| dir.is_a?(Array)}
return include_dirs return include_dirs
end end
def extract_headers(filename) def extract_headers(filename)
includes = [] includes = []
lines = File.readlines(filename) lines = File.readlines(filename)
lines.each do |line| lines.each do |line|
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/) m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/)
if not m.nil? if not m.nil?
includes << m[1] includes << m[1]
end end
end end
return includes return includes
end end
def find_source_file(header, paths) def find_source_file(header, paths)
paths.each do |dir| paths.each do |dir|
src_file = dir + header.ext(C_EXTENSION) src_file = dir + header.ext(C_EXTENSION)
if (File.exists?(src_file)) if (File.exists?(src_file))
return src_file return src_file
end end
end end
return nil return nil
end end
def tackit(strings) def tackit(strings)
if strings.is_a?(Array) if strings.is_a?(Array)
result = "\"#{strings.join}\"" result = "\"#{strings.join}\""
else else
result = strings result = strings
end end
return result return result
end end
def squash(prefix, items) def squash(prefix, items)
result = '' result = ''
items.each { |item| result += " #{prefix}#{tackit(item)}" } items.each { |item| result += " #{prefix}#{tackit(item)}" }
return result return result
end end
def build_compiler_fields def build_compiler_fields
command = tackit($cfg['compiler']['path']) command = tackit($cfg['compiler']['path'])
if $cfg['compiler']['defines']['items'].nil? if $cfg['compiler']['defines']['items'].nil?
defines = '' defines = ''
else else
defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items']) defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'])
end end
options = squash('', $cfg['compiler']['options']) options = squash('', $cfg['compiler']['options'])
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
return {:command => command, :defines => defines, :options => options, :includes => includes} return {:command => command, :defines => defines, :options => options, :includes => includes}
end end
def compile(file, defines=[]) def compile(file, defines=[])
compiler = build_compiler_fields compiler = build_compiler_fields
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " + cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " +
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" "#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}"
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}" obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}"
execute(cmd_str + obj_file) execute(cmd_str + obj_file)
return obj_file return obj_file
end end
def build_linker_fields def build_linker_fields
command = tackit($cfg['linker']['path']) command = tackit($cfg['linker']['path'])
if $cfg['linker']['options'].nil? if $cfg['linker']['options'].nil?
options = '' options = ''
else else
options = squash('', $cfg['linker']['options']) options = squash('', $cfg['linker']['options'])
end end
if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?) if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?)
includes = '' includes = ''
else else
includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items']) includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items'])
end end
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR)
return {:command => command, :options => options, :includes => includes} return {:command => command, :options => options, :includes => includes}
end end
def link_it(exe_name, obj_list) def link_it(exe_name, obj_list)
linker = build_linker_fields linker = build_linker_fields
cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " + cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " +
(obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join + (obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join +
$cfg['linker']['bin_files']['prefix'] + ' ' + $cfg['linker']['bin_files']['prefix'] + ' ' +
$cfg['linker']['bin_files']['destination'] + $cfg['linker']['bin_files']['destination'] +
exe_name + $cfg['linker']['bin_files']['extension'] exe_name + $cfg['linker']['bin_files']['extension']
execute(cmd_str) execute(cmd_str)
end end
def build_simulator_fields def build_simulator_fields
return nil if $cfg['simulator'].nil? return nil if $cfg['simulator'].nil?
if $cfg['simulator']['path'].nil? if $cfg['simulator']['path'].nil?
command = '' command = ''
else else
command = (tackit($cfg['simulator']['path']) + ' ') command = (tackit($cfg['simulator']['path']) + ' ')
end end
if $cfg['simulator']['pre_support'].nil? if $cfg['simulator']['pre_support'].nil?
pre_support = '' pre_support = ''
else else
pre_support = squash('', $cfg['simulator']['pre_support']) pre_support = squash('', $cfg['simulator']['pre_support'])
end end
if $cfg['simulator']['post_support'].nil? if $cfg['simulator']['post_support'].nil?
post_support = '' post_support = ''
else else
post_support = squash('', $cfg['simulator']['post_support']) post_support = squash('', $cfg['simulator']['post_support'])
end end
return {:command => command, :pre_support => pre_support, :post_support => post_support} return {:command => command, :pre_support => pre_support, :post_support => post_support}
end end
def execute(command_string, verbose=true, raise_on_fail=true) def execute(command_string, verbose=true, raise_on_fail=true)
report command_string report command_string
output = `#{command_string}`.chomp output = `#{command_string}`.chomp
report(output) if (verbose && !output.nil? && (output.length > 0)) report(output) if (verbose && !output.nil? && (output.length > 0))
if (($?.exitstatus != 0) and (raise_on_fail)) if (($?.exitstatus != 0) and (raise_on_fail))
raise "Command failed. (Returned #{$?.exitstatus})" raise "Command failed. (Returned #{$?.exitstatus})"
end end
return output return output
end end
def report_summary def report_summary
summary = UnityTestSummary.new summary = UnityTestSummary.new
summary.set_root_path(HERE) summary.set_root_path(HERE)
results_glob = "#{$cfg['compiler']['build_path']}*.test*" results_glob = "#{$cfg['compiler']['build_path']}*.test*"
results_glob.gsub!(/\\/, '/') results_glob.gsub!(/\\/, '/')
results = Dir[results_glob] results = Dir[results_glob]
summary.set_targets(results) summary.set_targets(results)
summary.run summary.run
fail_out "FAIL: There were failures" if (summary.failures > 0) fail_out "FAIL: There were failures" if (summary.failures > 0)
end end
def run_tests(test_files) def run_tests(test_files)
report 'Running system tests...' report 'Running system tests...'
# Tack on TEST define for compiling unit tests # Tack on TEST define for compiling unit tests
load_configuration($cfg_file) load_configuration($cfg_file)
test_defines = ['TEST'] test_defines = ['TEST']
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil? $cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil?
$cfg['compiler']['defines']['items'] << 'TEST' $cfg['compiler']['defines']['items'] << 'TEST'
include_dirs = get_local_include_dirs include_dirs = get_local_include_dirs
# Build and execute each unit test # Build and execute each unit test
test_files.each do |test| test_files.each do |test|
obj_list = [] obj_list = []
# Detect dependencies and build required required modules # Detect dependencies and build required required modules
extract_headers(test).each do |header| extract_headers(test).each do |header|
# Compile corresponding source file if it exists # Compile corresponding source file if it exists
src_file = find_source_file(header, include_dirs) src_file = find_source_file(header, include_dirs)
if !src_file.nil? if !src_file.nil?
obj_list << compile(src_file, test_defines) obj_list << compile(src_file, test_defines)
end end
end end
# Build the test runner (generate if configured to do so) # Build the test runner (generate if configured to do so)
test_base = File.basename(test, C_EXTENSION) test_base = File.basename(test, C_EXTENSION)
runner_name = test_base + '_Runner.c' runner_name = test_base + '_Runner.c'
if $cfg['compiler']['runner_path'].nil? if $cfg['compiler']['runner_path'].nil?
runner_path = $cfg['compiler']['build_path'] + runner_name runner_path = $cfg['compiler']['build_path'] + runner_name
test_gen = UnityTestRunnerGenerator.new($cfg_file) test_gen = UnityTestRunnerGenerator.new($cfg_file)
test_gen.run(test, runner_path) test_gen.run(test, runner_path)
else else
runner_path = $cfg['compiler']['runner_path'] + runner_name runner_path = $cfg['compiler']['runner_path'] + runner_name
end end
obj_list << compile(runner_path, test_defines) obj_list << compile(runner_path, test_defines)
# Build the test module # Build the test module
obj_list << compile(test, test_defines) obj_list << compile(test, test_defines)
# Link the test executable # Link the test executable
link_it(test_base, obj_list) link_it(test_base, obj_list)
# Execute unit test and generate results file # Execute unit test and generate results file
simulator = build_simulator_fields simulator = build_simulator_fields
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension']
if simulator.nil? if simulator.nil?
cmd_str = executable cmd_str = executable
else else
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}" cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}"
end end
output = execute(cmd_str, true, false) output = execute(cmd_str, true, false)
test_results = $cfg['compiler']['build_path'] + test_base test_results = $cfg['compiler']['build_path'] + test_base
if output.match(/OK$/m).nil? if output.match(/OK$/m).nil?
test_results += '.testfail' test_results += '.testfail'
else else
test_results += '.testpass' test_results += '.testpass'
end end
File.open(test_results, 'w') { |f| f.print output } File.open(test_results, 'w') { |f| f.print output }
end end
end end
def build_application(main) def build_application(main)
report "Building application..." report "Building application..."
obj_list = [] obj_list = []
load_configuration($cfg_file) load_configuration($cfg_file)
main_path = $cfg['compiler']['source_path'] + main + C_EXTENSION main_path = $cfg['compiler']['source_path'] + main + C_EXTENSION
# Detect dependencies and build required required modules # Detect dependencies and build required required modules
include_dirs = get_local_include_dirs include_dirs = get_local_include_dirs
extract_headers(main_path).each do |header| extract_headers(main_path).each do |header|
src_file = find_source_file(header, include_dirs) src_file = find_source_file(header, include_dirs)
if !src_file.nil? if !src_file.nil?
obj_list << compile(src_file) obj_list << compile(src_file)
end end
end end
# Build the main source file # Build the main source file
main_base = File.basename(main_path, C_EXTENSION) main_base = File.basename(main_path, C_EXTENSION)
obj_list << compile(main_path) obj_list << compile(main_path)
# Create the executable # Create the executable
link_it(main_base, obj_list) link_it(main_base, obj_list)
end end
def fail_out(msg) def fail_out(msg)
puts msg puts msg
exit(-1) exit(-1)
end end
end end
Example Project Example 3
=========
This example project gives an example of some passing, ignored, and failing tests.
It's simple and meant for you to look over and get an idea for what all of this stuff does. This example project gives an example of some passing, ignored, and failing tests.
It's simple and meant for you to look over and get an idea for what all of this stuff does.
You can build and test using the makefile if you have gcc installed (you may need to tweak
the locations of some tools in the makefile). Otherwise, the rake version will let you You can build and test using the makefile if you have gcc installed (you may need to tweak
test with gcc or a couple versions of IAR. You can tweak the yaml files to get those versions the locations of some tools in the makefile). Otherwise, the rake version will let you
running. test with gcc or a couple versions of IAR. You can tweak the yaml files to get those versions
running.
Ruby is required if you're using the rake version (obviously). This version shows off most of
Unity's advanced features (automatically creating test runners, fancy summaries, etc.) Ruby is required if you're using the rake version (obviously). This version shows off most of
Unity's advanced features (automatically creating test runners, fancy summaries, etc.)
The makefile version doesn't require anything outside of your normal build tools, but won't do the
extras for you. So that you can test right away, we've written the test runners for you and The makefile version doesn't require anything outside of your normal build tools, but won't do the
put them in the test\no_ruby subdirectory. If you make changes to the tests or source, you might extras for you. So that you can test right away, we've written the test runners for you and
need to update these (like when you add or remove tests). Do that for a while and you'll learn put them in the test\no_ruby subdirectory. If you make changes to the tests or source, you might
need to update these (like when you add or remove tests). Do that for a while and you'll learn
why you really want to start using the Ruby tools. why you really want to start using the Ruby tools.
\ No newline at end of file
#include "ProductionCode.h"
int Counter = 0;
int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; //some obnoxious array to search that is 1-based indexing instead of 0.
// This function is supposed to search through NumbersToFind and find a particular number.
// If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since
// NumbersToFind is indexed from 1. Unfortunately it's broken
// (and should therefore be caught by our tests)
int FindFunction_WhichIsBroken(int NumberToFind)
{
int i = 0;
while (i <= 8) //Notice I should have been in braces
i++;
if (NumbersToFind[i] == NumberToFind) //Yikes! I'm getting run after the loop finishes instead of during it!
return i;
return 0;
}
int FunctionWhichReturnsLocalVariable(void)
{
return Counter;
}
int FindFunction_WhichIsBroken(int NumberToFind);
int FunctionWhichReturnsLocalVariable(void);
#include "ProductionCode2.h"
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction)
{
//Since There Are No Tests Yet, This Function Could Be Empty For All We Know.
// Which isn't terribly useful... but at least we put in a TEST_IGNORE so we won't forget
return (char*)0;
}
char* ThisFunctionHasNotBeenTested(int Poor, char* LittleFunction);
# Copied from ~Unity/targets/gcc_32.yml
unity_root: &unity_root '../..'
compiler:
path: gcc
source_path: 'src/'
unit_tests_path: &unit_tests_path 'test/'
build_path: &build_path 'build/'
options:
- '-c'
- '-m32'
- '-Wall'
- '-Wno-address'
- '-std=c99'
- '-pedantic'
includes:
prefix: '-I'
items:
- 'src/'
- '../../src/'
- *unit_tests_path
defines:
prefix: '-D'
items:
- UNITY_INCLUDE_DOUBLE
- UNITY_SUPPORT_TEST_CASES
object_files:
prefix: '-o'
extension: '.o'
destination: *build_path
linker:
path: gcc
options:
- -lm
- '-m32'
includes:
prefix: '-I'
object_files:
path: *build_path
extension: '.o'
bin_files:
prefix: '-o'
extension: '.exe'
destination: *build_path
colour: true
:unity:
:plugins: []
#include "ProductionCode.h"
#include "unity.h"
//sometimes you may want to get at local data in a module.
//for example: If you plan to pass by reference, this could be useful
//however, it should often be avoided
extern int Counter;
void setUp(void)
{
//This is run before EACH TEST
Counter = 0x5a5a;
}
void tearDown(void)
{
}
void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void)
{
//All of these should pass
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(1));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(999));
TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(-1));
}
void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void)
{
// You should see this line fail in your test summary
TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34));
// Notice the rest of these didn't get a chance to run because the line above failed.
// Unit tests abort each test function on the first sign of trouble.
// Then NEXT test function runs as normal.
TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888));
}
void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void)
{
//This should be true because setUp set this up for us before this test
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
//This should be true because we can still change our answer
Counter = 0x1234;
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
}
void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void)
{
//This should be true again because setup was rerun before this test (and after we changed it to 0x1234)
TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable());
}
void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void)
{
//Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell
// you what actually happened...which in this case was a failure to setup the initial condition.
TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable());
}
#include "ProductionCode2.h"
#include "unity.h"
/* These should be ignored because they are commented out in various ways:
#include "whatever.h"
*/
//#include "somethingelse.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_IgnoredTest(void)
{
TEST_IGNORE_MESSAGE("This Test Was Ignored On Purpose");
}
void test_AnotherIgnoredTest(void)
{
TEST_IGNORE_MESSAGE("These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet");
}
void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void)
{
TEST_IGNORE(); //Like This
}
/* AUTOGENERATED FILE. DO NOT EDIT. */
#include "unity.h"
#include <setjmp.h>
#include <stdio.h>
char MessageBuffer[50];
extern void setUp(void);
extern void tearDown(void);
extern void test_IgnoredTest(void);
extern void test_AnotherIgnoredTest(void);
extern void test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented(void);
static void runTest(UnityTestFunction test)
{
if (TEST_PROTECT())
{
setUp();
test();
}
if (TEST_PROTECT() && !TEST_IS_IGNORED)
{
tearDown();
}
}
void resetTest()
{
tearDown();
setUp();
}
int main(void)
{
Unity.TestFile = "test/TestProductionCode2.c";
UnityBegin();
// RUN_TEST calls runTest
RUN_TEST(test_IgnoredTest, 13);
RUN_TEST(test_AnotherIgnoredTest, 18);
RUN_TEST(test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented, 23);
UnityEnd();
return 0;
}
/* AUTOGENERATED FILE. DO NOT EDIT. */
#include "unity.h"
#include <setjmp.h>
#include <stdio.h>
char MessageBuffer[50];
extern void setUp(void);
extern void tearDown(void);
extern void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void);
extern void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void);
extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void);
static void runTest(UnityTestFunction test)
{
if (TEST_PROTECT())
{
setUp();
test();
}
if (TEST_PROTECT() && !TEST_IS_IGNORED)
{
tearDown();
}
}
void resetTest()
{
tearDown();
setUp();
}
int main(void)
{
Unity.TestFile = "test/TestProductionCode.c";
UnityBegin();
// RUN_TEST calls runTest
RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode, 20);
RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken, 30);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue, 41);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain, 51);
RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed, 57);
UnityEnd();
return 0;
}
Eclipse error parsers
=====================
These are a godsend for extracting & quickly navigating to
warnings & error messages from console output. Unforunately
I don't know how to write an Eclipse plugin so you'll have
to add them manually.
To add a console parser to Eclipse, go to Window --> Preferences
--> C/C++ --> Build --> Settings. Click on the 'Error Parsers'
tab and then click the 'Add...' button. See the table below for
the parser fields to add.
Eclipse will only parse the console output during a build, so
running your unit tests must be part of your build process.
Either add this to your make/rakefile, or add it as a post-
build step in your Eclipse project settings.
Unity unit test error parsers
-----------------------------
Severity Pattern File Line Description
-------------------------------------------------------------------------------
Error (\.+)(.*?):(\d+):(.*?):FAIL: (.*) $2 $3 $5
Warning (\.+)(.*?):(\d+):(.*?):IGNORE: (.*) $2 $3 $5
Warning (\.+)(.*?):(\d+):(.*?):IGNORE\s*$ $2 $3 Ignored test
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册