Showing posts with label James Grenning. Show all posts
Showing posts with label James Grenning. Show all posts

Sunday, March 27, 2011

Test Driven Development in Embedded C class synopsis

This week I spent three days with James Grenning, and ten other gentlemen, to be educated in Test Driven Development for Embedded C at the LeanDog boat in Cleveland Ohio.

For some background Jack Ganssle did a two part interview with Mr. Grenning last summer [2010], on the subject of TDD in Embedded Development:
A majority of the course is based on James' about to be released new book [May 2011] Test Driven Development for Embedded C, and a lot of insights drawn from his background in agile development methods, James was one of the signers of the Agile Manifesto and Embedded Systems.



The premise of TDD is that you write the tests for the code that needs to be created, before the first line of code is ever written. How can you possible know if your code is bug free if you can not figure out how to write a test for it? As each small test case is written, you watch it fail, then write the code that is being tested, then run the test again to see that it passes. In the method of design from the top down and build from the bottom up, our products now are being built from a solid foundation of small tested functions, rather than on untested code full of unknown bugs, sinking in the Big Ball of Mud.

More thought is put into the upfront requirements (the what of the product and how it gets validated) and specifications (the how the product gets built and verified), rather than seeing the schedule slip month by month trying to get all of the bugs out of the code by heroic effort at the end of the development process.

In the words of Confucius: "I hear and I forget. I see and I remember. I do and I understand." A large part of the class was hands on examples of writing tests for supplied examples, and then seeing how our version compared to that written by James. Some of the examples had deliberate bugs and build traps that those new to TDD would fall into, such as a module being pulled from a library causing a name clash when a header file gets edited. There is the real production code, test code, and sometimes fake or 'mock' code. The 'mock' code takes the place of some item that does not yet exist or would be to time consuming to test. If things were not set up correctly the fake/mock code would collide with the real production code. Myself in this one case I still think I prefer using Makefiles and different build directories rather than James' linker library method. Neither is right or wrong, but a mater of taste and style.
All of the tests were run using the test harness cppUTest, which can test plan old C code and C++ code.

TDD is not just for brand new projects, it is equally suited to cleaning up the tangled mess that some legacy code has become after years of changes by different people. Part of the class was on 'refactoring' and the difference between that and redesigning the code, and how to apply the test cases. Pick out a single area of code with the end target to be a single well tested function. When tests have been established for the existing code the code is incrementally moved, in small steps, to get visibility points for more tests, until the code can be replaced with new tested clean code. James and the book are far more eloquent at describing the process than I have been here. James' blog and papers, several covering Embedded Systems, are a great resource to take advantage of, for example: Legacy Code Change - a Boy Scout Adds Tests.

One of the other tools mentioned, but not actually used in class is FitNesse acceptance testing framework.

Alas TDD is not a panacea for all of our collective code problems. It may not cover integration issues such has multi-threading race conditions [Use the Erlang principles of modify nothing and everything is a message, and threading issues vanish, even on MultiCore parts], it also might not find issues that are dependent on the target hardware integer size, when the host and target differ, unless the tests can also be run on the target, which is strongly recommended when possible.

At lunch Jon Stahl, our gracious host for the three day class, the owner of LeanDog, gave us lunch time talks, such has the one on Agile & Lean From The Top Down: Executives Practicing Agile and Seeing Constraints, Kanban Explained. Take a look at the slides to see the LeanDog Boat, the floating office, and the Lean Dog's themselves, Otis and Iggy. Talk to Jon about improving your bottom line in your business area and/or your software development area.

Also it is always good to get out, as sometimes you learn things at lunch that you would never know about such as The Tau Manifesto on how Pi is (still) wrong [YouTube Video]...

If you have the opportunity to take James TDDinC class when he is in your area, make the time for it, and if you are in Cleveland stop and say hello to Otis and Iggy, and sign up for some traning.

Sunday, March 13, 2011

James Grenning to present "Test is not for finding bugs", Cleveland March 23, 2011, 5:30PM

James_Grenning_March23_2011_Event_Flyer

It is with great pleasure that Firmware Engineers of Northeast Ohio, Cleveland Agile Group (CleAg), and the IEEE Cleveland Computer Society welcome James Grenning. He will be speaking to us at our upcoming event on March 23rd, 2011.

James Grenning trains, coaches, and consults worldwide. His considerable experience brings depth in both technical and business aspects of software development. James is leading the way in introducing Agile practices to the embedded world. He invented Planning Poker and is one of the original authors of the Manifesto for Agile Software Development (February 2001).

Mr. Grenning will present "Test is not for finding bugs".

Test is something that has to get done sometime before shipping the product. Test can wait while we do the important work of specifying, designing and coding the system. Test helps find bugs. Test happens at the end.

Wait! Don’t quote me on that!

Test is not that unpleasant activity at the end of the *development phase*, it is an integral and critical part of everyday work. It does not add drudgery, and overhead, it adds rewarding feedback and makes it possible to put more value into the software instead of wasting time chasing bugs. Test is not about finding bugs anymore. Test is specification; test is defect prevention, test drives good designs. Tests must be largely automated. You may think that you cannot afford to automate; when in reality, you cannot afford not to.

This will be the first time that Cleveland Agile Group (CleAg) and FENEO/IEEE have joined forces to bring such talent to Cleveland.


Donations are very welcome and appreciated. A donation box will be available at the sign in table. Please make all checks out to IEEE Cleveland. Also, FENEO is always looking for new sponsors.


Space is limited! To reserve your seat, please RSVP by March 21 at http://www.clevelandieee.org/jgrsvp.

Tuesday, February 22, 2011

Test Driven Development with Embedded C - Discount through Friday Feb 28th

We need just three more people to bring James Grenning to Cleveland next month.

If you were on the fence about signing up, there is now a twenty percent discount if you sign up before 4PM EST on the 28th of February. Enter the code "FENEO", for Firmware Engineers of Northeast Ohio (FENEO).

See my last blog entry Test Driven Development Embedded C with James Grenning March 22nd to 24th in Cleveland for details.

Sunday, August 22, 2010

Automatic Serial Number for Test Driven Development. Makefile Tip #0

With the pending release of James Grenning's new book Test Driven Development for Embedded C there has been a lot interest in TDD in the embedded space.


Jack Ganssle did a two part interview with Mr. Grenning this summer [2010], on the subject of TDD in Embedded Development:




Something that I have found very useful is an automatic build or serial number generated with each invocation of Make. The number can be accessed from C for use in version messages, or in the output from the invocation of Make directly.


This technique came out of a discussion by Matt VanDeWerk and Dave Hylands on the AVR-GCC list in 2005.


Create a file called 'buildnumber' that says this in the same directory as your Makefile:


#-------------------Cut Line -----------------------------------#
# This is the current build number of the latest build
# DO NOT EDIT THIS FILE - it is updated automagically
# by the build process.

BUILDNUMBER=0
#-------------------Cut Line -----------------------------------#

In the Makefile add these lines:


#-------------------Cut Line -----------------------------------#
# Add before any 'all:', or other target:
# Auto-incrementing number, which may be used in version numbers:
include buildnumber
NEW_BUILDNUMBER = $(shell echo $$(( $(BUILDNUMBER) + 1 )))

CDEFS += -DNEW_BUILDNUMBER=$(NEW_BUILDNUMBER)
CDEFS += -DNEW_BUILDNUMBER_TEXT=\"$(NEW_BUILDNUMBER)\"

%.elf: $(OBJ)
 @echo Test run: $(NEW_BUILDNUMBER)
# Do normal stuff here, append these two lines, which rewrite the
# buildnumber file for the next Make invocation:
 @echo "# Automatically generated file - do not edit" > buildnumber
 @echo "BUILDNUMBER=$(NEW_BUILDNUMBER)" >> buildnumber
#-------------------Cut Line -----------------------------------#

/*-------------------Cut Line -----------------------------------*/
/* C Example usage:
static uint8_t const BuildNumber_str[] = NEW_BUILDNUMBER_TEXT; /* Build number */
/*-------------------Cut Line -----------------------------------*/

Make does not get enough credit for being the powerful tool that it is.