SlideShare uma empresa Scribd logo
1 de 88
1
James W Grenning
wingman-sw.com
@jwgrenning
There is a Lot to TDD
2
We’ll Look at a Few Parts of TDD
3
There’s more.
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Are These the Questions I Should Answer?
• Why should I care about TDD?
• What is TDD?
• How do I test code with dependencies?
• How is TDD adapted to embedded development?
• What are some of the unique problems?
4
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
devconfu
Riga, Latvia
www.renaissancesoftware.net
james@renaissancesoftware.net
Copyright © 2008-2013 James W. Grenning	

All Rights Reserved.
Agile without TDD
with Hardening Sprints
5
Sprint 1 Sprint 2 Sprint 3 Sprint 4 Hardening Sprint
Test and Fix
Test and Fix Test and Fix
Test and Fix
Test and FixTest and Fix
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
This Work Flow is Designed to
Produce Defects
Development
Test
Defects
6
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Your program will have
bugs. And they will
surprise you when you
find them.
7
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Edsger Dijkstra
Those who want really reliable
software will discover that they must
find means of avoiding the majority
of bugs to start with, and as a result,
the programming process will
become cheaper. If you want more
effective programmers, you will
discover that they should not waste
their time debugging, they should
not introduce the bugs to start with.
8
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
9
Can we Realize Dijkstra’s
Dream and
Prevent Defects with
Test Driven Development?
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
The Physics of Debug Later
Programming (DLP)
• As Td increases, Tfind increases dramatically
• Tfix is usually short, but can increase with Td
Bug discoveryMistake made
(bug injection)
Bug found Bug fixed
Td Tfind T fix
Time
10
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
A Bug’s Life
From http://www.softwaretestinghelp.com/bug-life-cycle/
11
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Zune 30G
12
Decem
ber31,2008
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
13
BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
14
One That Got Away
static void SetYearAndDayOfYear(RtcTime* time)	
{	
int days = time->daysSince1980;	
int year = STARTING_YEAR;	
while (days > 365)	
{	
if (IsLeapYear(year))	
{	
if (days > 366)	
{	
days -= 366;	
year += 1;	
}	
}	
else	
{	
days -= 365;	
year += 1;	
}	
}	
!
time->dayOfYear = days;	
time->year = year;	
}
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
15
Your program will have
bugs. And they will
surprise you when you
find them.
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
16
This Test Could Have Prevented it
TEST(Rtc, check20081231)	
{	
days = daysSince1980(2008, 366);	
CHECK(ConvertDays(days, &time));	
assertDate(WED, 2008, 12, 31);	
}	
!
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
What is TDD?
17
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
• Write a test
• Watch it not build
• Make it build, but fail
• Make it pass
• Refactor (clean up any mess)
• Repeat until done
T
D
D
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning. Test Driven Development
www.renaissancesoftware.net
james@renaissancesoftware.net
Copyright © 2008-2013 James W. Grenning	

All Rights Reserved. For use by training attendees.
If test moved upstream, could we get
working features to flow?
19
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Development and Test are a Continuum
preventing defects
20
Development
Test
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
The Physics of Test Driven
Development
• When Td approaches zero, Tfind approaches zero
• In many cases, bugs are not around long enough to be considered
bugs.
• See: http://www.renaissancesoftware.net/blog/archives/16
Mistake
discovery
Mistake
made
Root cause
found
Mistake fixed
T d Tfind T fix
Time
21
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Let’s Test-Drive a CircularBuffer that
Holds Integers
+ Put
+ Get
+ IsEmpty
+ IsFull
//etc
CircularBuffer
22
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Create a Test-List
(avoid analysis paralysis)
Circular Buffer Tests
Initially Empty
Transition to empty
Transition to Full
Transition from Full
Put-Get FIFO
Put to full
Get from empty
Filled but not wrapped around
Wrap around
23
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Have an Idea of How it Will Work
Out-Index In-Index
23 7 66 12 99 16 90
Out-Index In-Index
42 -6 23 7 66 12 99 16 90
Out-Index In-Index
99
24
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Setup a Test Fixture
TEST_GROUP(CircularBuffer)	
{	
CircularBuffer* buffer;	
!
void setup()	
{	
buffer = CircularBuffer_Create();	
}	
!
void teardown()	
{	
CircularBuffer_Destroy(buffer);	
}	
};	
!
TEST(CircularBuffer, TestName)	
{	
}
25
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Make a Bare Skeleton of the
Production Code Header File
#ifndef D_CircularBuffer_H	
#define D_CircularBuffer_H	
!
typedef struct CircularBuffer CircularBuffer;	
!
CircularBuffer * CircularBuffer_Create();	
void CircularBuffer_Destroy(CircularBuffer *);	
!
#endif // D_CircularBuffer_H	
26
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Make a Bare Skeleton of the
Production Code Source File
#include "CircularBuffer.h"	
#include <stdlib.h>	
!
struct CircularBuffer	
{	
int dummy;	
} ;	
!
CircularBuffer* CircularBuffer_Create()	
{	
CircularBuffer* self = calloc(1, sizeof(CircularBuffer));	
return self;	
}	
!
void CircularBuffer_Destroy(CircularBuffer* self)	
{	
free(self);	
}	
!
27
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Choose a Test
Write the test
Make the test
link
Make the test
compile
Compilation error
Link error
New test failsMake the test pass
Refactor
(Make it right)
All tests pass
All tests pass
No more tests
Choose a test
Start
Compilation error
Link error
DONE!
Programming error
Compiles Clean
28
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Which Test Should We Start With?
Out-Index In-Index
41 59 14 33 7 31
In-Index Out-Index
29
30
TEST(CircularBuffer, empty_after_creation)	
{	
CHECK_TRUE(CircularBuffer_IsEmpty(buffer));	
}	
!
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
31
bool CircularBuffer_IsEmpty(CircularBuffer * self)	
{	
return true;	
}	
!
!
The Simplest Implementation
That Passes All Tests
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
32
TEST(CircularBuffer, empty_after_creation)	
{	
CHECK_TRUE(CircularBuffer_IsEmpty(buffer));	
}	
!
TEST(CircularBuffer, not_empty_after_put)	
{	
CircularBuffer_Put(buffer, 42);	
CHECK_FALSE(CircularBuffer_IsEmpty(buffer));	
}	
!
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
33
bool CircularBuffer_IsEmpty(CircularBuffer * self)	
{	
return self->index == 0;	
}	
!
void CircularBuffer_Put(CircularBuffer * self, int value)	
{	
self->index++	
}	
!
!
!
The Simplest Implementation
That Passes All Tests
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
34
TEST(CircularBuffer, empty_after_creation)	
{	
CHECK_TRUE(CircularBuffer_IsEmpty(buffer));	
}	
!
TEST(CircularBuffer, not_empty_after_put)	
{	
CircularBuffer_Put(buffer, 42);	
CHECK_FALSE(CircularBuffer_IsEmpty(buffer));	
}	
!
TEST(CircularBuffer, empty_after_removing_the_last_item)	
{	
CircularBuffer_Put(buffer, 42);	
CHECK_FALSE(CircularBuffer_IsEmpty(buffer));	
CircularBuffer_Get(buffer);	
CHECK_TRUE(CircularBuffer_IsEmpty(buffer));	
}	
!
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
35
bool CircularBuffer_IsEmpty(CircularBuffer * self)	
{	
return self->index == self->outputIndex;	
}	
!
void CircularBuffer_Put(CircularBuffer * self, int value)	
{	
self->index++	
}	
!
int CircularBuffer_Get(CircularBuffer * self)	
{	
self->outputIndex++	
return -1;	
}	
!
!
!
! The Simplest Implementation
That Passes All Tests
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees.
Coding is Dangerous
So We Work Carefully
• TDD is solving one
problem at a time.
!
• At first we focus on the
tests, with incomplete
code.
!
• Once all the tests are done,
the code is ready for
integration.
36
Photo by Andrew Bossi (Own work) [CC-BY-SA-2.5
(www.creativecommons.org/licenses/by-sa/2.5)], via
Wikimedia Commons
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Exercise
37
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
A Complex system that
works is invariably
found to have evolved
from a simple system
that worked.
38
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
39
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Debug
Sustainability
40
Traditional
development
The cost of
doing business
debug-later-
programming
Test-driven
development
Speculate Code Test/Debug Debug
Specu-
late
Test and Code Debug
Side-effect
Defect
Debug
Debug
Debug
Side-effect
Defect
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
TDD Helps Manage Cognitive Load
41
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Debug Later Programming is Like
Juggling
42
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
How Many Knives Do
You Like to Juggle?
• TDD is solving one
problem at a time
Photo by Andrew Bossi (Own work) [CC-BY-SA-2.5
(www.creativecommons.org/licenses/by-sa/2.5)], via
Wikimedia Commons
43
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
!
!
• Get good at being careful and you can go fast.
• Get good at solving one problem at a time.
Careful, the fast way is.
44
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Adaptation for Embedded
Software
45
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
What is special about embedded
• Concurrent HW development
• HW bottleneck
• Cross compilation
• Limited memory and IO
• Target debug
• Architecture
46
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
47
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Hardware is
Scarce!
• It does not exist.
• It is being used by
someone else.
• It has bugs of its
own.
48
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
49
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
50
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Minimize
Debug
on
Hardware
DoH!
Copyright Fox Broadcasting. Used under fair use.
51
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Write a Test
Make it Pass
Refactor
Stage 1
Compile
for Target
Processor
Stage 2
Run Tests
in the Eval
Hardware
Stage 3
Run Tests
in Target
Hardware
Stage 4
Acceptance
Tests
Stage 5
More Frequent Less Frequent
TDD Adaptation for Embedded
Development
52
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
TDD Adaptation for Embedded
Development
See : http://renaissancesoftware.net/files/articles/ProgressBeforeHardware.pdf
Write a Test
Make it Pass
Refactor
Stage 1
Compile
for Target
Processor
Stage 2
Run Tests
in the Eval
Hardware
Stage 3
Run Tests
in Target
Hardware
Stage 4
Acceptance
Tests
Stage 5
More Frequent Less Frequent
53
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
35
Continuous Integration - Embedded
3. CIS notices changes, refreshes its
local copy, builds and runs host
based tests.
2. Developer
checks in work
regularly.
1. Developer has
all unit tests
passing and
checks in work.
4. After successful
host build/test, CIS
builds and hands
images to TMS to
deploy to
simulator, eval/
reference boards
or target system.
The SCR, CIS and TMS are not necessarily
separate hardware systems.
Developer
Workstation
Source Code
Repository
Continuous Integration
Server
Target System
Eval/Reference
System
Simulator
Test Management
System
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Problems Found at Appropriate Stage
Stage Problems Likely to Find in Stage
1 Logic, design, modularity, interface, boundary conditions
2 Compiler compatibility (language features)!
Library compatibility (header files, declarations)
3 Processor executions problems (compiler and library bugs)!
Portability problems (word size, alignment, endian)
4 Ditto stage 3!
Hardware integration problems!
Misunderstood hardware specifications
5 Ditto stage 4!
Misunderstood feature specification
55
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
How do I test Code with
Dependencies?
56
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Spaghetti Slide
57
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
A Module with Collaborators
• Every minute, the
RTOS wakes up
the Light
Scheduler.
• If it is time for
one of the lights to
be controlled, the
LightController is
told to turn on/off
the light.
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ScheduleTurnOn()
+RemoveSchedule()
+WakeUp()
Light Controller
+ On(id)
+ Off(id)
Hardware RTOS
<<anonymous callback>>
Admin
Console
58
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Program to Interfaces
• Separate interface
and implementation
as separate entities.
• This design has
good separation of
responsibilities
<<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ ScheduleTurnOn()
+ RemoveSchedule()
+WakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
Model 42 Hardware RTOS
<<anonymous callback>>
Model 42
Light Controller
RTOS
Time Service
<<implements>> <<implements>>
Admin
Console
59
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Testing a Module with Collaborators
• Use the real
collaborators if
you can.
• Use fakes when
you must. <<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
Test
Light
Scheduler
+ ScheduleTurnOn()
+ RemoveSchedule()
+wakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
Light Controller
Spy
Fake
Time Service
<<implements>> <<implements>>
60
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Testing the Scheduler
TEST(LightScheduler, ScheduleOnTodayNotTimeYet)	
{	
LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1000);	
FakeTimeSource_SetMinute(999);	
!
LightScheduler_Wakeup();	
!
LONGS_EQUAL(LIGHT_NA, LightControllerSpy_GetState(3));	
}	
!
TEST(LightScheduler, ScheduleOnTodayItsTime)	
{	
LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1000);	
FakeTimeSource_SetMinute(1000);	
!
LightScheduler_Wakeup();	
!
LONGS_EQUAL(LIGHT_ON, LightControllerSpy_GetState(3));	
}	
61
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Partial Skeleton Let’s You Try the
Design and Test Ideas Early
62
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Test-Doubles
63
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Test Double
• A test double stands in for some part of the
production code during testing
• Test doubles are part of the test fixture that allows a
module to be unit tested
64
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Test Dependency Octopus
65
Test
Code
Under Test
Depended
On
Component
DOC DOC
Transitively
DOC
TDOC TDOCTDOCTDOC
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Managing the Octopus
66
Test
Code
Under Test
Test Double Test Double Test Double
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Use Production Code when you Can
Test Doubles when you Must
67
Test
Code
Under Test
Depended
On
Component
Test Double Test Double
Transitively
DOC
TDOC
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Kinds of Test Doubles
[XUNIT]
• Other names
– Fakes
– Mock object
– Spy
– Null object
– Exploding fakes
– there are others
68
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
What are the Test Double
Options in C?
• Link-time substitution.
– Substitute whole object files or libraries
• Run time substitution.
– Function pointers.
– Function pointer tables.
• Preprocessor substitution
– My least favorite, but sometimes necessary
• Use the simplest option that will work.
69
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
What are the Test Doubles
Options in C++?
• Link-time substitution.
– Substitute whole object files or libraries
• Run time substitution.
– To substitute one class for another
– Virtual functions.
– Interface classes.
– To substitute one function for another
– C function pointers.
• Preprocessor substitution
– my least favorite, but sometimes necessary
• Use the simplest option that will work.
70
CppUMock
Mocking the Hardware
71__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
TDD One Instruction
from the Hardware
72__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
#include "IOReadWrite.h"	
!
IOData * ioBase = (IOData *)0xdeadbeef;	
!
IOData IORead(IOAddress offset)	
{	
return *(ioBase+offset);	
}	
void IOWrite(IOAddress offset, IOData data)	
{	
*(ioBase+offset) = data;	
}	
#include <stdint.h>	
!
typedef uint32_t IOAddress;	
typedef uint16_t IOData;	
!
IOData IORead(IOAddress offset);	
void IOWrite(IOAddress offset, IOData data);
Flash Program Flow Chart
73__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
How Many Tests are Needed?
b7 == 1
Start
Begin
Programming mode
Write(0x0, 0x40)
Start/Stop
Write(Address,
data)
Read status
register Read(0x0)
b3 == 0
b4 == 0
b1 == 0
YES
NO
YES
YES
YES
Vpp Error
Program Error
Protected Block
Error
NO
NO
NO
Clear status
Write 0xFF to 0x0
Waitforreadyloop
How do
you test
these
errors in
the target?
How do
you test
these
errors in
the target?
CppUMock
• Let’s you set expectations for a series of calls on an
object or function
• Let’s CppUMock know when the code under test calls
the mocked API
• Let’s mock the IOReadWrite API
74__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
#include <stdint.h>	
!
typedef uint32_t IOAddress;	
typedef uint16_t IOData;	
!
IOData IORead(IOAddress offset);	
void IOWrite(IOAddress offset, IOData data);
Flash Driver Test Fixture
75__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
<<implementation>>
IO
<<implements>>
+ Read(addr) : data
+ Write(addr, data)
<<interface>>
IO
+ Expect_Read(addr, data)
+ Expect_Write(addr, data)
MockIO
<<hardware>>
+ Program(addr, data)
+ ProtectBlock(block)
+ EraseBlock(block)
//etc
FlashDriver
FlashDriverTest
#include "IOReadWrite.h"	
!
IOData * ioBase = (IOData *)0xdeadbeef;	
!
IOData IORead(IOAddress offset)	
{	
return *(ioBase+offset);	
}	
void IOWrite(IOAddress offset, IOData data)	
{	
*(ioBase+offset) = data;	
}	
#include <stdint.h>	
!
typedef uint32_t IOAddress;	
typedef uint16_t IOData;	
!
IOData IORead(IOAddress offset);	
void IOWrite(IOAddress offset, IOData data);
76__EVENT__ www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-20XX James W. Grenning	

All Rights Reserved. For use by training attendees. Test Doubles
<<implementation>>
IO
<<implements>>
+ Read(addr) : data
+ Write(addr, data)
<<interface>>
IO
+ Expect_Read(addr, data)
+ Expect_Write(addr, data)
MockIO
<<hardware>>
+ Program(addr, data)
+ ProtectBlock(block)
+ EraseBlock(block)
//etc
FlashDriver
FlashDriverTest
void IOWrite(IOAddress addr, IOData data)	
{	
mock("IO")	
.actualCall("IOWrite")	
.withParameter("addr", (int)addr)	
.withParameter("data", (int)data);	
}	
!
IOData IORead(IOAddress addr)	
{	
return mock("IO")	
.actualCall("IORead")	
.withParameter("addr", (int)addr)	
.returnValue().getIntValue();	
}	
TEST(Flash, Program_succeeds_ready_immediately)	
{	
mock("IO")	
.expectOneCall("IOWrite")	
.withParameter("addr", 0x0)	
.withParameter("data", 0x40);	
mock("IO")	
.expectOneCall("IOWrite")	
.withParameter("addr", 1000)	
.withParameter("data", 9999);	
mock("IO")	
.expectOneCall("IORead")	
.withParameter("addr", 0x0)	
.andReturnValue(1<<7);	
!
LONGS_EQUAL(FLASH_OK, FlashProgram(1000, 9999));	
}
Expectations are defined and recorded
in the test case by CppUMock.
Expectations are matched by
CppUMock when the actual calls to
the mock version of the functions are
reported via actualCall().
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Getting Around Tool
Dependencies
77
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Example Problems
• Compiler vendors extend C
• Embedded ‘asm’
• Header files lock you to the vendor
78
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Compiler vendors extend C
79
//snip...!
/* Address Mode Register */!
extern cregister volatile unsigned int AMR; !
//snip...!
!
//snip...!
interrupt void one_ms_tic(void)!
{!
...!
}!
//snip...
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Hide Them with a
Preprocessor Forced Include
80
//hide_stuff.h	
!
#define interrupt	
#define cregister	
!
Force Include hidestuff.h, to make them go away
read the blog: http://www.renaissancesoftware.net/blog/archives/
249
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Developers embed ‘asm’
81
void foo(void)	
{	
	 do	
	 {	
	 asm("NOP");	
	 asm("PLOP");	
	 asm("READ 0");	
	 status = IORead(0);	
	 } while ((status &amp; ReadyBit) == 0);	
}
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Hide asm Forced Include
82
//nullasm.h	
!
#define asm	
!
Force Include nullasm.h, to make asm go away
read the blog: http://www.renaissancesoftware.net/blog/archives/
136
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
AsmSpy Test Double
83
#define asm AsmSpy	
!
void AsmSpy_Create(int size);	
void AsmSpy_Destroy(void);	
void AsmSpy(const char *);	
const char * AsmSpy_Debrief(void);	
Force Include AsmSpy.h All asm() directives are
converted to AsmSpy() calls, allowing capture.
read the blog: http://www.renaissancesoftware.net/blog/archives/
136
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
AsmSpy Tests Show How to Monitor
the asm
84
TEST(AsmSpy, CaptureAsmInstructions)	
{	
	 AsmSpy("NOP");	
	 AsmSpy("FLOP");	
	 AsmSpy("POP");	
	 STRCMP_EQUAL("NOP;FLOP;POP;", AsmSpy_Debrief());	
}	
!
Force Include AsmSpy.h, to capture asm instructions
read the blog: http://www.renaissancesoftware.net/blog/archives/
136
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Header Files that Lock You to the
Vendor’s Compiler
85
#if defined(_ACME_X42)	
typedef unsigned int Uint_32;	
typedef unsigned short Uint_16;	
typedef unsigned char Uint_8;	
	
typedef int Int_32;	
typedef short Int_16;	
typedef char Int_8;	
#elif defined(_ACME_A12)	
typedef unsigned long Uint_32;	
typedef unsigned int Uint_16;	
typedef unsigned char Uint_8;	
	
typedef long Int_32;	
typedef int Int_16;	
typedef char Int_8;	
#else	
#error <acmetypes.h> is not supported for this environment	
#endif
Test-Driven Development for C/C++ Hands-On
OOP Conference 2015 #OOP2015
www.wingman-sw.com
oop@wingman-sw.com
Copyright © 2008-2015 James W. Grenning	

All Rights Reserved @jwgrenning.
Create a #include Test Double
86
#include <stdint.h>	
!
typedef uint32_t	 	 Uint_32;	
typedef uint16_t	 	 Uint_16;	
typedef uint8_t	 	 Uint_8;	
!
typedef int32_t	 	 Int_32;	
typedef int16_t	 	 Int_16;	
typedef int8_t	 	 Int_8;	
!
#endif /* ACMETYPES_H_ */	
Also, limit dependencies on vendor specific includes
There is a Lot More to TDD
87
88
Talk to me on Twitter
@jwgrenning!
!
Find my book at!
http://www.wingman-sw.com/tddec!
http://www.pragprog.com/titles/jgade
!
Find me on linkedin.com
http://www.linkedin.com/in/jwgrenning
Please remind me how we met.
!
http://www.wingman-sw.com
http://www.wingman-sw.com/blog
http:// www.jamesgrenning.com

Mais conteúdo relacionado

Mais procurados

自動テスト知識体系TABOKのご紹介
自動テスト知識体系TABOKのご紹介自動テスト知識体系TABOKのご紹介
自動テスト知識体系TABOKのご紹介Shinsuke Matsuki
 
Lexical Analysis - Compiler Design
Lexical Analysis - Compiler DesignLexical Analysis - Compiler Design
Lexical Analysis - Compiler DesignAkhil Kaushik
 
An Introduction to the C++ Standard Library
An Introduction to the C++ Standard LibraryAn Introduction to the C++ Standard Library
An Introduction to the C++ Standard LibraryJoyjit Choudhury
 
Rotor Cipher and Enigma Machine
Rotor Cipher and Enigma MachineRotor Cipher and Enigma Machine
Rotor Cipher and Enigma MachineSaurabh Kaushik
 
Multithreading in java
Multithreading in javaMultithreading in java
Multithreading in javaArafat Hossan
 
Easymock Tutorial
Easymock TutorialEasymock Tutorial
Easymock TutorialSbin m
 
キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015Toru Koido
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
 
TestNG Session presented in Xebia XKE
TestNG Session presented in Xebia XKETestNG Session presented in Xebia XKE
TestNG Session presented in Xebia XKEAbhishek Yadav
 
EMTEを使って自動化の費用対効果をわかりやすく表現する
EMTEを使って自動化の費用対効果をわかりやすく表現するEMTEを使って自動化の費用対効果をわかりやすく表現する
EMTEを使って自動化の費用対効果をわかりやすく表現するJYERUEY
 
はじめての自己組織化
はじめての自己組織化はじめての自己組織化
はじめての自己組織化Yoshinori Ueda
 
テスト計画セッション
テスト計画セッションテスト計画セッション
テスト計画セッションTomoaki Fukura
 
[OOP - Lec 08] Encapsulation (Information Hiding)
[OOP - Lec 08] Encapsulation (Information Hiding)[OOP - Lec 08] Encapsulation (Information Hiding)
[OOP - Lec 08] Encapsulation (Information Hiding)Muhammad Hammad Waseem
 

Mais procurados (20)

TDD Best Practices
TDD Best PracticesTDD Best Practices
TDD Best Practices
 
自動テスト知識体系TABOKのご紹介
自動テスト知識体系TABOKのご紹介自動テスト知識体系TABOKのご紹介
自動テスト知識体系TABOKのご紹介
 
Lexical Analysis - Compiler Design
Lexical Analysis - Compiler DesignLexical Analysis - Compiler Design
Lexical Analysis - Compiler Design
 
Corso Java 1 - BASE
Corso Java 1 - BASECorso Java 1 - BASE
Corso Java 1 - BASE
 
Angular Fundamentals
Angular FundamentalsAngular Fundamentals
Angular Fundamentals
 
An Introduction to the C++ Standard Library
An Introduction to the C++ Standard LibraryAn Introduction to the C++ Standard Library
An Introduction to the C++ Standard Library
 
How java differs from c and c++
How java differs from c and c++How java differs from c and c++
How java differs from c and c++
 
sets and maps
 sets and maps sets and maps
sets and maps
 
Rotor Cipher and Enigma Machine
Rotor Cipher and Enigma MachineRotor Cipher and Enigma Machine
Rotor Cipher and Enigma Machine
 
Multithreading in java
Multithreading in javaMultithreading in java
Multithreading in java
 
Easymock Tutorial
Easymock TutorialEasymock Tutorial
Easymock Tutorial
 
キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015
 
EasyMock for Java
EasyMock for JavaEasyMock for Java
EasyMock for Java
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
TestNG Session presented in Xebia XKE
TestNG Session presented in Xebia XKETestNG Session presented in Xebia XKE
TestNG Session presented in Xebia XKE
 
Turbo prolog 2.0 basics
Turbo prolog 2.0 basicsTurbo prolog 2.0 basics
Turbo prolog 2.0 basics
 
EMTEを使って自動化の費用対効果をわかりやすく表現する
EMTEを使って自動化の費用対効果をわかりやすく表現するEMTEを使って自動化の費用対効果をわかりやすく表現する
EMTEを使って自動化の費用対効果をわかりやすく表現する
 
はじめての自己組織化
はじめての自己組織化はじめての自己組織化
はじめての自己組織化
 
テスト計画セッション
テスト計画セッションテスト計画セッション
テスト計画セッション
 
[OOP - Lec 08] Encapsulation (Information Hiding)
[OOP - Lec 08] Encapsulation (Information Hiding)[OOP - Lec 08] Encapsulation (Information Hiding)
[OOP - Lec 08] Encapsulation (Information Hiding)
 

Semelhante a Test-Driven Development for Embedded C -- OOP Conference 2015, Munich

MARISA SAWATPHADUNGKIJ
MARISA SAWATPHADUNGKIJMARISA SAWATPHADUNGKIJ
MARISA SAWATPHADUNGKIJAlisha Kapoor
 
Typescript vas ES6
Typescript vas ES6Typescript vas ES6
Typescript vas ES6Haim Michael
 
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)Sebastian Hensiek
 
通往測試最高殿堂的旅程 - GTAC 2016
通往測試最高殿堂的旅程 - GTAC 2016通往測試最高殿堂的旅程 - GTAC 2016
通往測試最高殿堂的旅程 - GTAC 2016Chloe Chen
 
Implementing Continuous Integration to Improve Software Quality
Implementing Continuous Integration to Improve Software QualityImplementing Continuous Integration to Improve Software Quality
Implementing Continuous Integration to Improve Software QualityRocket Software
 
Big feature - small sprint
Big feature - small sprint Big feature - small sprint
Big feature - small sprint Igor Goldshmidt
 
More Agile and LeSS dysfunction - may 2015
More Agile and LeSS dysfunction - may 2015More Agile and LeSS dysfunction - may 2015
More Agile and LeSS dysfunction - may 2015Rowan Bunning
 
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom Provider
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom ProviderRemoving Crucial Dependencies to Enable KPN as a Virtual Telecom Provider
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom ProviderCA Technologies
 
TypeScript Seminar
TypeScript SeminarTypeScript Seminar
TypeScript SeminarHaim Michael
 
Test driven development_continuous_integration
Test driven development_continuous_integrationTest driven development_continuous_integration
Test driven development_continuous_integrationhaochenglee
 
Programmer Anarchy and Managerless Processes
Programmer Anarchy and Managerless ProcessesProgrammer Anarchy and Managerless Processes
Programmer Anarchy and Managerless ProcessesFred George
 
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...CA Technologies
 
Leadership Summit - Association of Inside Sales Professionals
Leadership Summit - Association of Inside Sales ProfessionalsLeadership Summit - Association of Inside Sales Professionals
Leadership Summit - Association of Inside Sales ProfessionalsDoug Devitre
 
DevOps presentation at gemeente Rotterdam
DevOps presentation at gemeente RotterdamDevOps presentation at gemeente Rotterdam
DevOps presentation at gemeente RotterdamMiel Donkers
 
Going Agile in a Multi-National Work Environment and the Tool We Chose
Going Agile in a Multi-National Work Environment and the Tool We ChoseGoing Agile in a Multi-National Work Environment and the Tool We Chose
Going Agile in a Multi-National Work Environment and the Tool We ChosePaula Stern
 
A Week in the Life (of DevOps)
A Week in the Life (of DevOps)A Week in the Life (of DevOps)
A Week in the Life (of DevOps)CA Technologies
 
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015Tealium
 
ASP.NET 5: What's the Big Deal
ASP.NET 5: What's the Big DealASP.NET 5: What's the Big Deal
ASP.NET 5: What's the Big DealJim Duffy
 

Semelhante a Test-Driven Development for Embedded C -- OOP Conference 2015, Munich (20)

MARISA SAWATPHADUNGKIJ
MARISA SAWATPHADUNGKIJMARISA SAWATPHADUNGKIJ
MARISA SAWATPHADUNGKIJ
 
Typescript vas ES6
Typescript vas ES6Typescript vas ES6
Typescript vas ES6
 
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)
Webinar: Taking your JMeter Test Monitoring To The Next Level (Ft. PerfAcademy)
 
通往測試最高殿堂的旅程 - GTAC 2016
通往測試最高殿堂的旅程 - GTAC 2016通往測試最高殿堂的旅程 - GTAC 2016
通往測試最高殿堂的旅程 - GTAC 2016
 
Five Flute Overview
Five Flute OverviewFive Flute Overview
Five Flute Overview
 
Implementing Continuous Integration to Improve Software Quality
Implementing Continuous Integration to Improve Software QualityImplementing Continuous Integration to Improve Software Quality
Implementing Continuous Integration to Improve Software Quality
 
Big feature - small sprint
Big feature - small sprint Big feature - small sprint
Big feature - small sprint
 
More Agile and LeSS dysfunction - may 2015
More Agile and LeSS dysfunction - may 2015More Agile and LeSS dysfunction - may 2015
More Agile and LeSS dysfunction - may 2015
 
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom Provider
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom ProviderRemoving Crucial Dependencies to Enable KPN as a Virtual Telecom Provider
Removing Crucial Dependencies to Enable KPN as a Virtual Telecom Provider
 
TypeScript Seminar
TypeScript SeminarTypeScript Seminar
TypeScript Seminar
 
Test driven development_continuous_integration
Test driven development_continuous_integrationTest driven development_continuous_integration
Test driven development_continuous_integration
 
Make the most of twig
Make the most of twigMake the most of twig
Make the most of twig
 
Programmer Anarchy and Managerless Processes
Programmer Anarchy and Managerless ProcessesProgrammer Anarchy and Managerless Processes
Programmer Anarchy and Managerless Processes
 
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...
Case Study: Citrix Adopts DevOps Principles to Gain Efficiency and Speed Soft...
 
Leadership Summit - Association of Inside Sales Professionals
Leadership Summit - Association of Inside Sales ProfessionalsLeadership Summit - Association of Inside Sales Professionals
Leadership Summit - Association of Inside Sales Professionals
 
DevOps presentation at gemeente Rotterdam
DevOps presentation at gemeente RotterdamDevOps presentation at gemeente Rotterdam
DevOps presentation at gemeente Rotterdam
 
Going Agile in a Multi-National Work Environment and the Tool We Chose
Going Agile in a Multi-National Work Environment and the Tool We ChoseGoing Agile in a Multi-National Work Environment and the Tool We Chose
Going Agile in a Multi-National Work Environment and the Tool We Chose
 
A Week in the Life (of DevOps)
A Week in the Life (of DevOps)A Week in the Life (of DevOps)
A Week in the Life (of DevOps)
 
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015
"Top Tips for Maximizing Tealium iQ" - First Data + WAD, Digital Velocity 2015
 
ASP.NET 5: What's the Big Deal
ASP.NET 5: What's the Big DealASP.NET 5: What's the Big Deal
ASP.NET 5: What's the Big Deal
 

Mais de James Grenning

Technical Excellence - OOP Munich 2015
Technical Excellence - OOP Munich 2015Technical Excellence - OOP Munich 2015
Technical Excellence - OOP Munich 2015James Grenning
 
Embedded Extreme Programming - Embedded Systems Conference 2002-2004
Embedded Extreme Programming - Embedded Systems Conference 2002-2004Embedded Extreme Programming - Embedded Systems Conference 2002-2004
Embedded Extreme Programming - Embedded Systems Conference 2002-2004James Grenning
 
Agile Embedded Software
Agile Embedded SoftwareAgile Embedded Software
Agile Embedded SoftwareJames Grenning
 
Beyond Planning Poker - Agile 2011
Beyond Planning Poker - Agile 2011Beyond Planning Poker - Agile 2011
Beyond Planning Poker - Agile 2011James Grenning
 
Designing SOLID C - ACCU Conference 2014
Designing SOLID C - ACCU Conference 2014Designing SOLID C - ACCU Conference 2014
Designing SOLID C - ACCU Conference 2014James Grenning
 

Mais de James Grenning (6)

Technical Excellence - OOP Munich 2015
Technical Excellence - OOP Munich 2015Technical Excellence - OOP Munich 2015
Technical Excellence - OOP Munich 2015
 
Embedded Extreme Programming - Embedded Systems Conference 2002-2004
Embedded Extreme Programming - Embedded Systems Conference 2002-2004Embedded Extreme Programming - Embedded Systems Conference 2002-2004
Embedded Extreme Programming - Embedded Systems Conference 2002-2004
 
Agile Embedded Software
Agile Embedded SoftwareAgile Embedded Software
Agile Embedded Software
 
Beyond Planning Poker - Agile 2011
Beyond Planning Poker - Agile 2011Beyond Planning Poker - Agile 2011
Beyond Planning Poker - Agile 2011
 
Designing SOLID C - ACCU Conference 2014
Designing SOLID C - ACCU Conference 2014Designing SOLID C - ACCU Conference 2014
Designing SOLID C - ACCU Conference 2014
 
Solid c-accu2014.key
Solid c-accu2014.keySolid c-accu2014.key
Solid c-accu2014.key
 

Último

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 

Último (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 

Test-Driven Development for Embedded C -- OOP Conference 2015, Munich

  • 2. There is a Lot to TDD 2
  • 3. We’ll Look at a Few Parts of TDD 3 There’s more.
  • 4. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Are These the Questions I Should Answer? • Why should I care about TDD? • What is TDD? • How do I test code with dependencies? • How is TDD adapted to embedded development? • What are some of the unique problems? 4
  • 5. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. devconfu Riga, Latvia www.renaissancesoftware.net james@renaissancesoftware.net Copyright © 2008-2013 James W. Grenning All Rights Reserved. Agile without TDD with Hardening Sprints 5 Sprint 1 Sprint 2 Sprint 3 Sprint 4 Hardening Sprint Test and Fix Test and Fix Test and Fix Test and Fix Test and FixTest and Fix
  • 6. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. This Work Flow is Designed to Produce Defects Development Test Defects 6
  • 7. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Your program will have bugs. And they will surprise you when you find them. 7
  • 8. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Edsger Dijkstra Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result, the programming process will become cheaper. If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with. 8
  • 9. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 9 Can we Realize Dijkstra’s Dream and Prevent Defects with Test Driven Development?
  • 10. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. The Physics of Debug Later Programming (DLP) • As Td increases, Tfind increases dramatically • Tfix is usually short, but can increase with Td Bug discoveryMistake made (bug injection) Bug found Bug fixed Td Tfind T fix Time 10
  • 11. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. A Bug’s Life From http://www.softwaretestinghelp.com/bug-life-cycle/ 11
  • 12. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Zune 30G 12 Decem ber31,2008
  • 13. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 13 BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
  • 14. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 14 One That Got Away static void SetYearAndDayOfYear(RtcTime* time) { int days = time->daysSince1980; int year = STARTING_YEAR; while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } ! time->dayOfYear = days; time->year = year; }
  • 15. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 15 Your program will have bugs. And they will surprise you when you find them.
  • 16. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 16 This Test Could Have Prevented it TEST(Rtc, check20081231) { days = daysSince1980(2008, 366); CHECK(ConvertDays(days, &time)); assertDate(WED, 2008, 12, 31); } !
  • 17. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. What is TDD? 17
  • 18. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. • Write a test • Watch it not build • Make it build, but fail • Make it pass • Refactor (clean up any mess) • Repeat until done T D D
  • 19. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Test Driven Development www.renaissancesoftware.net james@renaissancesoftware.net Copyright © 2008-2013 James W. Grenning All Rights Reserved. For use by training attendees. If test moved upstream, could we get working features to flow? 19
  • 20. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Development and Test are a Continuum preventing defects 20 Development Test
  • 21. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. The Physics of Test Driven Development • When Td approaches zero, Tfind approaches zero • In many cases, bugs are not around long enough to be considered bugs. • See: http://www.renaissancesoftware.net/blog/archives/16 Mistake discovery Mistake made Root cause found Mistake fixed T d Tfind T fix Time 21
  • 22. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Let’s Test-Drive a CircularBuffer that Holds Integers + Put + Get + IsEmpty + IsFull //etc CircularBuffer 22
  • 23. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Create a Test-List (avoid analysis paralysis) Circular Buffer Tests Initially Empty Transition to empty Transition to Full Transition from Full Put-Get FIFO Put to full Get from empty Filled but not wrapped around Wrap around 23
  • 24. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Have an Idea of How it Will Work Out-Index In-Index 23 7 66 12 99 16 90 Out-Index In-Index 42 -6 23 7 66 12 99 16 90 Out-Index In-Index 99 24
  • 25. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Setup a Test Fixture TEST_GROUP(CircularBuffer) { CircularBuffer* buffer; ! void setup() { buffer = CircularBuffer_Create(); } ! void teardown() { CircularBuffer_Destroy(buffer); } }; ! TEST(CircularBuffer, TestName) { } 25
  • 26. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Make a Bare Skeleton of the Production Code Header File #ifndef D_CircularBuffer_H #define D_CircularBuffer_H ! typedef struct CircularBuffer CircularBuffer; ! CircularBuffer * CircularBuffer_Create(); void CircularBuffer_Destroy(CircularBuffer *); ! #endif // D_CircularBuffer_H 26
  • 27. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Make a Bare Skeleton of the Production Code Source File #include "CircularBuffer.h" #include <stdlib.h> ! struct CircularBuffer { int dummy; } ; ! CircularBuffer* CircularBuffer_Create() { CircularBuffer* self = calloc(1, sizeof(CircularBuffer)); return self; } ! void CircularBuffer_Destroy(CircularBuffer* self) { free(self); } ! 27
  • 28. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Choose a Test Write the test Make the test link Make the test compile Compilation error Link error New test failsMake the test pass Refactor (Make it right) All tests pass All tests pass No more tests Choose a test Start Compilation error Link error DONE! Programming error Compiles Clean 28
  • 29. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Which Test Should We Start With? Out-Index In-Index 41 59 14 33 7 31 In-Index Out-Index 29
  • 31. 31 bool CircularBuffer_IsEmpty(CircularBuffer * self) { return true; } ! ! The Simplest Implementation That Passes All Tests __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees.
  • 32. 32 TEST(CircularBuffer, empty_after_creation) { CHECK_TRUE(CircularBuffer_IsEmpty(buffer)); } ! TEST(CircularBuffer, not_empty_after_put) { CircularBuffer_Put(buffer, 42); CHECK_FALSE(CircularBuffer_IsEmpty(buffer)); } ! __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees.
  • 33. 33 bool CircularBuffer_IsEmpty(CircularBuffer * self) { return self->index == 0; } ! void CircularBuffer_Put(CircularBuffer * self, int value) { self->index++ } ! ! ! The Simplest Implementation That Passes All Tests __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees.
  • 34. 34 TEST(CircularBuffer, empty_after_creation) { CHECK_TRUE(CircularBuffer_IsEmpty(buffer)); } ! TEST(CircularBuffer, not_empty_after_put) { CircularBuffer_Put(buffer, 42); CHECK_FALSE(CircularBuffer_IsEmpty(buffer)); } ! TEST(CircularBuffer, empty_after_removing_the_last_item) { CircularBuffer_Put(buffer, 42); CHECK_FALSE(CircularBuffer_IsEmpty(buffer)); CircularBuffer_Get(buffer); CHECK_TRUE(CircularBuffer_IsEmpty(buffer)); } ! __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees.
  • 35. 35 bool CircularBuffer_IsEmpty(CircularBuffer * self) { return self->index == self->outputIndex; } ! void CircularBuffer_Put(CircularBuffer * self, int value) { self->index++ } ! int CircularBuffer_Get(CircularBuffer * self) { self->outputIndex++ return -1; } ! ! ! ! The Simplest Implementation That Passes All Tests __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees.
  • 36. __EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Coding is Dangerous So We Work Carefully • TDD is solving one problem at a time. ! • At first we focus on the tests, with incomplete code. ! • Once all the tests are done, the code is ready for integration. 36 Photo by Andrew Bossi (Own work) [CC-BY-SA-2.5 (www.creativecommons.org/licenses/by-sa/2.5)], via Wikimedia Commons
  • 37. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Exercise 37
  • 38. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. A Complex system that works is invariably found to have evolved from a simple system that worked. 38
  • 39. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 39
  • 40. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Debug Sustainability 40 Traditional development The cost of doing business debug-later- programming Test-driven development Speculate Code Test/Debug Debug Specu- late Test and Code Debug Side-effect Defect Debug Debug Debug Side-effect Defect
  • 41. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. TDD Helps Manage Cognitive Load 41
  • 42. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Debug Later Programming is Like Juggling 42
  • 43. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. How Many Knives Do You Like to Juggle? • TDD is solving one problem at a time Photo by Andrew Bossi (Own work) [CC-BY-SA-2.5 (www.creativecommons.org/licenses/by-sa/2.5)], via Wikimedia Commons 43
  • 44. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. ! ! • Get good at being careful and you can go fast. • Get good at solving one problem at a time. Careful, the fast way is. 44
  • 45. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Adaptation for Embedded Software 45
  • 46. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. What is special about embedded • Concurrent HW development • HW bottleneck • Cross compilation • Limited memory and IO • Target debug • Architecture 46
  • 47. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 47
  • 48. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Hardware is Scarce! • It does not exist. • It is being used by someone else. • It has bugs of its own. 48
  • 49. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 49
  • 50. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 50
  • 51. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Minimize Debug on Hardware DoH! Copyright Fox Broadcasting. Used under fair use. 51
  • 52. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Write a Test Make it Pass Refactor Stage 1 Compile for Target Processor Stage 2 Run Tests in the Eval Hardware Stage 3 Run Tests in Target Hardware Stage 4 Acceptance Tests Stage 5 More Frequent Less Frequent TDD Adaptation for Embedded Development 52
  • 53. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. TDD Adaptation for Embedded Development See : http://renaissancesoftware.net/files/articles/ProgressBeforeHardware.pdf Write a Test Make it Pass Refactor Stage 1 Compile for Target Processor Stage 2 Run Tests in the Eval Hardware Stage 3 Run Tests in Target Hardware Stage 4 Acceptance Tests Stage 5 More Frequent Less Frequent 53
  • 54. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. 35 Continuous Integration - Embedded 3. CIS notices changes, refreshes its local copy, builds and runs host based tests. 2. Developer checks in work regularly. 1. Developer has all unit tests passing and checks in work. 4. After successful host build/test, CIS builds and hands images to TMS to deploy to simulator, eval/ reference boards or target system. The SCR, CIS and TMS are not necessarily separate hardware systems. Developer Workstation Source Code Repository Continuous Integration Server Target System Eval/Reference System Simulator Test Management System
  • 55. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Problems Found at Appropriate Stage Stage Problems Likely to Find in Stage 1 Logic, design, modularity, interface, boundary conditions 2 Compiler compatibility (language features)! Library compatibility (header files, declarations) 3 Processor executions problems (compiler and library bugs)! Portability problems (word size, alignment, endian) 4 Ditto stage 3! Hardware integration problems! Misunderstood hardware specifications 5 Ditto stage 4! Misunderstood feature specification 55
  • 56. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. How do I test Code with Dependencies? 56
  • 57. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Spaghetti Slide 57
  • 58. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. A Module with Collaborators • Every minute, the RTOS wakes up the Light Scheduler. • If it is time for one of the lights to be controlled, the LightController is told to turn on/off the light. Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler +ScheduleTurnOn() +RemoveSchedule() +WakeUp() Light Controller + On(id) + Off(id) Hardware RTOS <<anonymous callback>> Admin Console 58
  • 59. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Program to Interfaces • Separate interface and implementation as separate entities. • This design has good separation of responsibilities <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler + ScheduleTurnOn() + RemoveSchedule() +WakeUp() <<interface>> Light Controller + On(id) + Off(id) Model 42 Hardware RTOS <<anonymous callback>> Model 42 Light Controller RTOS Time Service <<implements>> <<implements>> Admin Console 59
  • 60. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Testing a Module with Collaborators • Use the real collaborators if you can. • Use fakes when you must. <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler Test Light Scheduler + ScheduleTurnOn() + RemoveSchedule() +wakeUp() <<interface>> Light Controller + On(id) + Off(id) Light Controller Spy Fake Time Service <<implements>> <<implements>> 60
  • 61. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Testing the Scheduler TEST(LightScheduler, ScheduleOnTodayNotTimeYet) { LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1000); FakeTimeSource_SetMinute(999); ! LightScheduler_Wakeup(); ! LONGS_EQUAL(LIGHT_NA, LightControllerSpy_GetState(3)); } ! TEST(LightScheduler, ScheduleOnTodayItsTime) { LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1000); FakeTimeSource_SetMinute(1000); ! LightScheduler_Wakeup(); ! LONGS_EQUAL(LIGHT_ON, LightControllerSpy_GetState(3)); } 61
  • 62. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Partial Skeleton Let’s You Try the Design and Test Ideas Early 62
  • 63. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Test-Doubles 63
  • 64. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Test Double • A test double stands in for some part of the production code during testing • Test doubles are part of the test fixture that allows a module to be unit tested 64
  • 65. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Test Dependency Octopus 65 Test Code Under Test Depended On Component DOC DOC Transitively DOC TDOC TDOCTDOCTDOC
  • 66. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Managing the Octopus 66 Test Code Under Test Test Double Test Double Test Double
  • 67. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Use Production Code when you Can Test Doubles when you Must 67 Test Code Under Test Depended On Component Test Double Test Double Transitively DOC TDOC
  • 68. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Kinds of Test Doubles [XUNIT] • Other names – Fakes – Mock object – Spy – Null object – Exploding fakes – there are others 68
  • 69. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. What are the Test Double Options in C? • Link-time substitution. – Substitute whole object files or libraries • Run time substitution. – Function pointers. – Function pointer tables. • Preprocessor substitution – My least favorite, but sometimes necessary • Use the simplest option that will work. 69
  • 70. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. What are the Test Doubles Options in C++? • Link-time substitution. – Substitute whole object files or libraries • Run time substitution. – To substitute one class for another – Virtual functions. – Interface classes. – To substitute one function for another – C function pointers. • Preprocessor substitution – my least favorite, but sometimes necessary • Use the simplest option that will work. 70
  • 71. CppUMock Mocking the Hardware 71__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles
  • 72. TDD One Instruction from the Hardware 72__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles #include "IOReadWrite.h" ! IOData * ioBase = (IOData *)0xdeadbeef; ! IOData IORead(IOAddress offset) { return *(ioBase+offset); } void IOWrite(IOAddress offset, IOData data) { *(ioBase+offset) = data; } #include <stdint.h> ! typedef uint32_t IOAddress; typedef uint16_t IOData; ! IOData IORead(IOAddress offset); void IOWrite(IOAddress offset, IOData data);
  • 73. Flash Program Flow Chart 73__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles How Many Tests are Needed? b7 == 1 Start Begin Programming mode Write(0x0, 0x40) Start/Stop Write(Address, data) Read status register Read(0x0) b3 == 0 b4 == 0 b1 == 0 YES NO YES YES YES Vpp Error Program Error Protected Block Error NO NO NO Clear status Write 0xFF to 0x0 Waitforreadyloop How do you test these errors in the target? How do you test these errors in the target?
  • 74. CppUMock • Let’s you set expectations for a series of calls on an object or function • Let’s CppUMock know when the code under test calls the mocked API • Let’s mock the IOReadWrite API 74__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles #include <stdint.h> ! typedef uint32_t IOAddress; typedef uint16_t IOData; ! IOData IORead(IOAddress offset); void IOWrite(IOAddress offset, IOData data);
  • 75. Flash Driver Test Fixture 75__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles <<implementation>> IO <<implements>> + Read(addr) : data + Write(addr, data) <<interface>> IO + Expect_Read(addr, data) + Expect_Write(addr, data) MockIO <<hardware>> + Program(addr, data) + ProtectBlock(block) + EraseBlock(block) //etc FlashDriver FlashDriverTest #include "IOReadWrite.h" ! IOData * ioBase = (IOData *)0xdeadbeef; ! IOData IORead(IOAddress offset) { return *(ioBase+offset); } void IOWrite(IOAddress offset, IOData data) { *(ioBase+offset) = data; } #include <stdint.h> ! typedef uint32_t IOAddress; typedef uint16_t IOData; ! IOData IORead(IOAddress offset); void IOWrite(IOAddress offset, IOData data);
  • 76. 76__EVENT__ www.wingman-sw.com james@wingman-sw.com Copyright © 2008-20XX James W. Grenning All Rights Reserved. For use by training attendees. Test Doubles <<implementation>> IO <<implements>> + Read(addr) : data + Write(addr, data) <<interface>> IO + Expect_Read(addr, data) + Expect_Write(addr, data) MockIO <<hardware>> + Program(addr, data) + ProtectBlock(block) + EraseBlock(block) //etc FlashDriver FlashDriverTest void IOWrite(IOAddress addr, IOData data) { mock("IO") .actualCall("IOWrite") .withParameter("addr", (int)addr) .withParameter("data", (int)data); } ! IOData IORead(IOAddress addr) { return mock("IO") .actualCall("IORead") .withParameter("addr", (int)addr) .returnValue().getIntValue(); } TEST(Flash, Program_succeeds_ready_immediately) { mock("IO") .expectOneCall("IOWrite") .withParameter("addr", 0x0) .withParameter("data", 0x40); mock("IO") .expectOneCall("IOWrite") .withParameter("addr", 1000) .withParameter("data", 9999); mock("IO") .expectOneCall("IORead") .withParameter("addr", 0x0) .andReturnValue(1<<7); ! LONGS_EQUAL(FLASH_OK, FlashProgram(1000, 9999)); } Expectations are defined and recorded in the test case by CppUMock. Expectations are matched by CppUMock when the actual calls to the mock version of the functions are reported via actualCall().
  • 77. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Getting Around Tool Dependencies 77
  • 78. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Example Problems • Compiler vendors extend C • Embedded ‘asm’ • Header files lock you to the vendor 78
  • 79. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Compiler vendors extend C 79 //snip...! /* Address Mode Register */! extern cregister volatile unsigned int AMR; ! //snip...! ! //snip...! interrupt void one_ms_tic(void)! {! ...! }! //snip...
  • 80. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Hide Them with a Preprocessor Forced Include 80 //hide_stuff.h ! #define interrupt #define cregister ! Force Include hidestuff.h, to make them go away read the blog: http://www.renaissancesoftware.net/blog/archives/ 249
  • 81. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Developers embed ‘asm’ 81 void foo(void) { do { asm("NOP"); asm("PLOP"); asm("READ 0"); status = IORead(0); } while ((status &amp; ReadyBit) == 0); }
  • 82. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Hide asm Forced Include 82 //nullasm.h ! #define asm ! Force Include nullasm.h, to make asm go away read the blog: http://www.renaissancesoftware.net/blog/archives/ 136
  • 83. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. AsmSpy Test Double 83 #define asm AsmSpy ! void AsmSpy_Create(int size); void AsmSpy_Destroy(void); void AsmSpy(const char *); const char * AsmSpy_Debrief(void); Force Include AsmSpy.h All asm() directives are converted to AsmSpy() calls, allowing capture. read the blog: http://www.renaissancesoftware.net/blog/archives/ 136
  • 84. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. AsmSpy Tests Show How to Monitor the asm 84 TEST(AsmSpy, CaptureAsmInstructions) { AsmSpy("NOP"); AsmSpy("FLOP"); AsmSpy("POP"); STRCMP_EQUAL("NOP;FLOP;POP;", AsmSpy_Debrief()); } ! Force Include AsmSpy.h, to capture asm instructions read the blog: http://www.renaissancesoftware.net/blog/archives/ 136
  • 85. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Header Files that Lock You to the Vendor’s Compiler 85 #if defined(_ACME_X42) typedef unsigned int Uint_32; typedef unsigned short Uint_16; typedef unsigned char Uint_8; typedef int Int_32; typedef short Int_16; typedef char Int_8; #elif defined(_ACME_A12) typedef unsigned long Uint_32; typedef unsigned int Uint_16; typedef unsigned char Uint_8; typedef long Int_32; typedef int Int_16; typedef char Int_8; #else #error <acmetypes.h> is not supported for this environment #endif
  • 86. Test-Driven Development for C/C++ Hands-On OOP Conference 2015 #OOP2015 www.wingman-sw.com oop@wingman-sw.com Copyright © 2008-2015 James W. Grenning All Rights Reserved @jwgrenning. Create a #include Test Double 86 #include <stdint.h> ! typedef uint32_t Uint_32; typedef uint16_t Uint_16; typedef uint8_t Uint_8; ! typedef int32_t Int_32; typedef int16_t Int_16; typedef int8_t Int_8; ! #endif /* ACMETYPES_H_ */ Also, limit dependencies on vendor specific includes
  • 87. There is a Lot More to TDD 87
  • 88. 88 Talk to me on Twitter @jwgrenning! ! Find my book at! http://www.wingman-sw.com/tddec! http://www.pragprog.com/titles/jgade ! Find me on linkedin.com http://www.linkedin.com/in/jwgrenning Please remind me how we met. ! http://www.wingman-sw.com http://www.wingman-sw.com/blog http:// www.jamesgrenning.com