Weitere ähnliche Inhalte Ähnlich wie 嵌入式測試驅動開發 (20) 嵌入式測試驅動開發10. TDD 循環
加 紅燈:增 一個運行失敗,
甚至無法 譯的測試
加 綠燈:快 修改, 做能讓
測試 過的工作
加 黃燈:重構,移除重複改進
代碼可讀性
Test Driven Development: By Example
19. 嵌入式驅動開發工具
加 Unity
– C 語言自動化測試框架
– 用 Ruby Script 安裝測試
加 CppUTest
– C/C++自動化測試框架
– 用 Ruby Script 測試轉
換 Unity 測試
Unity http://throwtheswitch.org/, CppUTest http://cpputest.github.io/
29. 寫 hardcode 讓測試 過
LedDriver.c
static uint16_t* ledsAddress;
void LedDriver_Create (uint16_t* address)
{
ledsAddress = address;
*ledsAddress = 0;
}
void LedDriver_TurnOn (int ledNumber)
{
*ledDriver = 1;
}
Data Encapsulation (資料封裝)
43. FakeTimeService.c
static int theMinute;
void FakeTimeService_SetMinute (int minute)
{
theMinute = minute;
}
void TimeService_GetTime (Time* time)
{
time->minuteOfDay = theMinute;
}
FakeTimeServiceTest.c
TEST (FakeTimeService, Set)
{
Time time;
FakeTimeService_SetMinute (42);
TimeService_GetTime (&time);
LONGS_EQUAL (42, time.minuteOfDay);
}
45. FakeTimeService.c
static int theMinute;
int FakeTimeService_GetMinute (void)
{
return theMinute;
}
void TimeService_SetDay (Time* time)
{
theMinute = time->minuteOfDay;
}
FakeTimeServiceTest.c
TEST (FakeTimeService, Get)
{
Time time;
time->minuteOfDay = 42;
TimeService_SetTime (&time);
LONGS_EQUAL (42, FakeTimeService_GetMinute());
}
48. FlashTest.c
TEST (Flash, WriteSucceeds)
{
int result = 0;
MockIO_Expect_Write (0, 0x40);
MockIO_Expect_Write (0x1000, 0xBEEF);
MockIO_Expect_ReadThenReturn (0, 1<<7);
MockIo_Expect_ReadThenReturn (0, 1<<7);
MockIO_Expect_ReadThenReturn (0x1000, 0xBEEF);
Result = Flash_Write (0x1000, 0xBEEF);
LONG_EQUAL (0, result);
MockIO_Verify_Complete();
}
CMock http://throwtheswitch.org/, CppUMock http://cpputest.github.io/
51. 用 C 語言實現資料封裝
WallClock.h
void WallClock_SetTime (Time time);
Time WallClock_GetTime (void);
Watch.h
typedef struct WatchStruct Watch;
void SetTime (Watch* watch, Time time);
Time GetTime (Watch* watch);
52. 用 C 語言實現類別繼
Watch.h
typedef struct WatchStruct {
void (*SetTime) (Watch*, Time);
Time (*GetTime) (Watch*);
} Watch;
interface
Watch
DigitalWatch.c
typedef struct DigitalWatchStruct {
Watch* base;
Time time;
} DigitalWatch;
Watch* DigitalWatch_Create (void) {
DigitalWatch* self = malloc(sizeof(DigitalWatch));
self->base->SetTime = mySetTime;
self->base->GetTime = myGetTime;
return (Watch*)self;
}
Digital
Watch
53. 用 C 語言實現類別多型
User.c
void doSetTime (Watch* watch, Time time) {
watch->SetTime (watch, time);
}
User
interface
Watch
DigitalWatch.c
static void mySetTime (Watch* watch, Time time)
{
DigitalWatch* self = (DigitalWatch*)watch;
self->time = time;
}
MechanicWatch.c
static void mySetTime (Watch* watch, Time time)
{
MechanicWatch* self = (MechanicWatch*)watch;
self->time = time;
}
Digital
Watch
Mechanic
Watch
57. CodeSmells.c
void foobar (Time* time, Work* work)
{
if (work->item != NULL) {
Day day = time->dayOfWeek;
int min = time->minuteOfDay;
if ((day >= MONDAY && day <= FRIDAY) &&
((min >= 9*60 && min <= 12*60) ||
(min >= 13*60 && min <= 18*60)) {
if (work->type == CODING)
doCode (work->item);
else
doDebug (work->item);
// doSomethingImportant ();
}
}
}
59. RefactoredCode.c
static bool isWorkTime (Time* time)
{
...
}
static void workHard (Work* work)
{
...
}
void workInOffice (Time* time, Work* work)
{
if (!isWorkTime(time))
return;
workHard (work);
}
71. 參考資料
Test-Driven Development for Embedded C
Test Driven Development: By Example
xUnit Test Patterns: Refactoring Test Code
Refactoring: Improving the Design of Existing Code
Working Efficiently with Legacy Code
Agile Software Development, Principle, Patterns, and Practices
Design Patterns for Embedded Systems in C: An Embedded
Software Engineering Toolkit