Agile TDD for Embedded Systems and Legacy Code: Course PLUS Your-Legacy-Code Clinic
Revision as of 16:27, 4 June 2011 by Clarman
This is a combination of a 2-3 day course with structured learning exercises, FOLLOWED BY a 2-3 day "clinic" or workshop applying the skills to your existing legacy code. (For a total of 4-5 days; the exact timing is content dependent on the knowledge of the developers, the state of the legacy code, and the legacy problems to tackle).
This information-packed and hands-on course shows developers and technical leaders how to apply test-driven development (TDD) and refactoring in the context of embedded systems and your related legacy code — almost always, C and/or C++, perhaps combined with some assembler.
TDD is powerful and practical. It’s the practice of always writing test code before the code to be tested, in small micro-test-and-develop cycles. In addition to the obvious benefits that (1) tests actually get written and executed for most code with thorough test coverage and (2) the practice and mindset of "building quality in" by test-FIRST rather than test-LAST (which tries to "inspect old defects out"), a more subtle but important benefit is that (3) when we start by thinking very concretely—with code—in the role of a calling client to the new code before it is written, it (4) clarifies our design, (5) tends to create better designs with lower coupling, higher cohesion, and flexible dependency injection, (6) and becomes a more fun and creative way to combine writing tests with code. Hence, TDD is far more than "just testing" — it is a kind of creative micro-design step.
In this course you will learn how to think in and apply test-driven design and programming, and establish it as a consistent method for your development team. You’ll learn and work with the popular TDD framework JUnit (if Java, or one of the other popular xUnit frameworks if working in another language).
TDD quickly leads developers to see the need for and value of reducing coupling in their code, and for techniques to break dependencies so that tests can be run quickly in isolation. Thus, a critical adjunct skill in TDD is learning how to create and inject alternate “test doubles” (fakes, stubs, ...). In this course you will learn how to create stubs, fakes, mocks, object factories/mothers, how to break dependencies, and how to apply dependency injection methods.
Learning how to break dependencies for testing in isolation is especially important in the context of legacy code; in this course you will to work with legacy code to “bring it under test” and apply TDD.
Refactoring is a disciplined design skill to improve the structure of code without changing its external behavior. And refactoring is part of the TDD cycle. Thus, in this course you will learn the various “code smells” and the refactorings to clean them up. Refactoring depends on automated refactoring tools built into popular IDEs or editors, such as Netbeans, Eclipse, SlickEdit, or emacs; thus in this course you will learn to apply an automated refactoring tool. Finally, the course includes a brief introduction to the companion agile methods practice called Acceptance TDD—executable requirements with automated verification. You will learn about the popular FIT framework and the Acceptance TDD methodology.
Methods of Education
Discussion, presentation, Q&A, workshop exercises
Developers, architects, test engineers, technical leaders.
Intermediate: This course introduces concepts and techniques that the attendee will apply during the workshop.
skill in an object-oriented programming language
Upon completion of this course, students should be able to:
- apply TDD
- break dependencies and create “test doubles” (fakes, mocks, stubs, ...)
- inject dependencies with flexible techniques
- separate test set up code into object factories or “object mothers”
- identify code smells
- apply refactorings
- use an xUnit framework such as Junit
- bring legacy code “under test”
- define acceptance TDD and the FIT framework
- Test-Driven Development
- Method and motivation
- Writing tests first
- The TDD lifecycle
- Testing in an iterative and agile method
- Categories of TDD: unit, acceptance
- TDD tools and frameworks
- Testing in different architectural layers
- TDD Tools
- Unit TDD
- Practice with XUnit
- Code smells
- Refactorings, including Extract Method, Introduce Explaining Variable, and dozens more
- Test Doubles: Fakes, Stub and Mock Objects
- Integration vs. unit testing
- Setting up the test environment
- Mock generation tools
- Object factories
- Object Mother pattern
- Dependency injection
- Dependency injection with Spring
- Continuous Integration and TDD
- Information radiators for CI
- Why do people delay integration?
- Acceptance TDD with FIT
- TDD and Legacy Code
- Characterization tests
- The Legacy TDD life cycle