Test Driven Development For Embedded C: The Physics of Debug Later Programming (DLP)
Test Driven Development For Embedded C: The Physics of Debug Later Programming (DLP)
Td
Tnd
T x Time
As Td increases, Tfind increases dramatically Tfix is usually short, but can increase with Td
http://pragprog.com/titles/jgade/
www.renaissancesoftware.net [email protected]
1
1
www.renaissancesoftware.net [email protected]
2
2
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
Copyright 2008-2010 James W. Grenning All Rights Reserved. www.renaissancesoftware.net [email protected]
3
3
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
4
4
Compilation error
23
66
12
99
16
90
99
Compiles Clean
Refactor (Make it right) DONE! All tests pass Link error Make the test compile Compilation error
Out-Index
In-Index
Programming error
Link error
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
5
5
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
6
6
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
7
7
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
8
8
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
9
9
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
10
10
Choose a Test
Start
Which Test?
Compilation error
Compiles Clean
Refactor (Make it right) DONE! All tests pass Link error Make the test compile Compilation error
Out-Index
In-Index
41
New test fails Make the test link Link error
59
14
33
31
Programming error
In-Index
Out-Index
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
11
11
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
12
12
Write a Test
Start
Compilation error
Compiles Clean
Refactor (Make it right) Make the test compile Link error Compilation error
Programming error
Link error
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
13
13
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
14
14
Start with a Test That is Easy to Get to Pass -- Designing the Interface
TEST_GROUP(CircularBuffer) { CircularBuffer* buffer; void setup() { buffer = CircularBuffer_Create(); } void teardown() { CircularBuffer_Destroy(buffer); } }; TEST(CircularBuffer, ShouldBeEmptyAfterCreate) {
CHECK(CircularBuffer_IsEmpty(buffer));
Programming error
Compilation error
Compiles Clean
Refactor (Make it right) DONE! All tests pass Link error Make the test compile Compilation error
Link error
}
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
15
15
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
16
16
Choose a test
CircularBuffer * CircularBuffer_Create(int capacity); void CircularBuffer_Destroy(CircularBuffer *); int CircularBuffer_IsEmpty(CircularBuffer *); #endif // D_CircularBuffer_H
Compiles Clean
Refactor (Make it right) DONE! All tests pass Link error Make the test compile Compilation error
Programming error
Link error
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
17
17
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
18
18
Watch it Fail
CircularBufferTest.cpp:48: error: Failure in TEST(CircularBuffer, EmptyAfterCreation) CHECK(CircularBuffer_IsEmpty(buffer)) failed
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
19
19
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
20
20
Compilation error
Compiles Clean
Refactor (Make it right) DONE! All tests pass Link error Make the test compile Compilation error
Programming error
Link error
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
21
21
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
22
22
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
23
23
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
24
24
25
25
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
26
26
Hardware is Scarce!
It does not exist. It is being used by someone else.
Hardware is Scarce!
It does not exist. It is being used by someone else.
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
27
27
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
28
28
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
29
29
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
30
30
www.renaissancesoftware.net [email protected]
31
31
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
32
32
Acceptance Tests
More Frequent
More Frequent
Less Frequent
Less Frequent
See : http://renaissancesoftware.net/files/articles/ProgressBeforeHardware.pdf
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
33
33
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
34
34
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
35
35
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
36
36
www.renaissancesoftware.net [email protected]
www.renaissancesoftware.net [email protected]
38
38
Program to Interfaces
Separate interface and implementation as separate entities. This design has good separation of responsibilities
Admin Console Light Scheduler +addSchedule() +removeSchedule() +wakeUp()
<<anonymous callback>>
<<interface>>
<<interface>>
Hardware
<<implements>>
Hardware
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
RTOS
www.renaissancesoftware.net [email protected]
www.renaissancesoftware.net [email protected]
39
39
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
40
40
<<interface>>
<<interface>>
<<implements>>
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
41
41
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
42
42
#endif
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
43
43
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
44
44
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
45
45
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
46
46
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
47
47
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
48
48
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
49
49
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
50
50
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
51
51
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
52
52
Add defining instance of the function pointer and initialize the pointer with the the _impl
//From the .c file ... static int RandomMinuteGenerator_Get_impl() { ...the implementation... } int (*RandomMinuteGenerator_Get)() = RandomMinuteGenerator_Get_impl;
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
53
53
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
54
54
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
55
55
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
56
56
Flash_Program(offset, data)
IOWrite(CommandRegister, 0x40)
IOWrite(offset, data)
Repeats while b7 == 0
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
57
57
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
58
58
Mock Object
Problem - Complex collaborator interactions cannot be captured with a simple spy. Solution - Mock Object
A Mock Object is a Test Double that verifies that the code being tested interacts with its collaborator properly. The test tells the mock
The expected calls In the expected order What to return.
NO
Vpp Error
YES
Write data to address
b4 == 0
NO
Program Error
YES
Read status register Protected Block Error
b1 == 0
NO
NO YES
b7 == 1 Start/Stop Clear status Write 0xFF to 0x0
YES
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
59
59
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
60
60
//IOReadWrite.h #include <stdint.h> typedef uint32_t ioAddress_t; typedef uint16_t ioData_t; ioData_t IORead(ioAddress_t offset ); void IOWrite(ioAddress_t offset, ioData_t data);
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
61
61
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
62
62
//Snip void MockIO_Create(int maxExpectations) { expectations = malloc(sizeof(Expectation)*maxExpectations); memset(expectations, 0, sizeof(expectations)); setExpectationCount = 0; getExpectationCount = 0; maxExpectationCount = maxExpectations; failureAlreadyReported = 0; }
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
63
63
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
64
64
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
65
65
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
66
66
Minimize DOH!
Debug On Hardware
www.renaissancesoftware.net [email protected]
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
67
67
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
68
68
On-line
Test harnesses
[CPPTEST] www.sourceforge.org, project CppUTest [FITNESSE] www.fitnesse.org
The End
Groups
http://groups.yahoo.com/group/testdrivendevelopment http://groups.yahoo.com/group/AgileEmbedded
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
69
69
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
70
70
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
71
71
www.renaissancesoftware.net [email protected]
72
72
Copyright 2008-2010 James W. Grenning All Rights Reserved. For use by training attendees.
www.renaissancesoftware.net [email protected]
73
73