Randori Sessions‎ > ‎

Foundations: TDD from the middle

posted Jan 2, 2011, 6:53 AM by Erik Przekop   [ updated Jan 7, 2011, 10:38 AM ]
This week's sessions will focus on TDD from the "middle" of the system.  (True "top-down" would be from the UI, but we'll save that for a later session.)

We will test drive a set of rules from the controller (a stand-in for a portlet), and create the database interactions as we go.  The idea is to set the expectations for what we want the database to do first, then implement the appropriate DAO and SQL.

The intent is to practice doing TDD the right way, while picking up tips and tricks from each other's experience.

This exercise features:
  • A "real world" problem, as requested by many of us after the last craft day.  (This will almost certainly take us through week 2, since these sessions are only 1 hour long.)  It uses Spring to inject the data source, pulls data from an Oracle database.
  • Hamcrest matchers for a DSL-like set of test assertions.
  • Doing TDD the right way - follow all of the rules outlined in the curriculum topics below.
  • Top-Down vs Bottom-Up testing.
Remember, testing the right way is more important than a complete solution - even though this is a real-world problem, it is not production code.  We're here to learn, not complete the story card.  Don't be shy about deleting code and doing it over in a different way to see what happens.

The Problem
We'll do something simple, but close enough to the real-world to be effective.  To keep it simple, we will use an existing table from Career Transitions, which contains information about careers.  Career data is organized into a hierarchy with career "clusters" at the top, a set of "pathways" within each cluster, and a set of careers within each pathway.  All of this data is stored in the CT_CAREERS table.

The concept is that the user can drill down through a tree of cluster->pathway->career, viewing an alphabetically sorted list of each at all three levels.

We will implement the following rules:
  1. The controller can get a list of career clusters, in alphabetical order.
  2. The controller can get a list of career pathways in alphabetical order by passing in the name of a career cluster.
  3. The controller can get a list of careers in alphabetical order, by passing in the name of a career pathway.

Curriculum topics covered
These sessions will cover all of the "foundation" TDD topics in our curriculum:
  • No production code without a test
    • The developer has the habit of writing tests first
    • The developer understands that different testing tools are useful at different levels (presentation, data, controller)
    • The developer knows how to use mocks to test objects that have not yet been implemented, and can use at least one mocking tool
  • Only enough code to make a test pass
    • The developer understands the concept of "emergent design", and can apply it
    • The developer does not create un-tested features
  • Red. Green. Refactor.  Don't skip any steps.
    • The developer only creates a test when under green
    • The developer only adds a new feature to production code under red
    • The developer always refactors production code under green
    • The developer looks for opportunities to refactor test code after adding each test

The curriculum mind-map is here.  You can download a copy of XMind here.


The exercise code.  (Requires the CT database to run.)

Why top-down testing & design?
  • Fun
  • Heckling
  • Feedback from peers
  • Setup / expectations were good
  • Good philosophical discussions
  • "Real" Gale problem
  • Move slowly
  • Purpose was unclear
  • Too much "legacy" code in the problem (should be clean slate for TDD practice)
  • Didn't focus on TDD - more focus on the problem itself.
Do Different:
  • Clean slate / no DAO layer (use mocks if we do a DB)
  • Put real functionality into the controller, not just pass-through to DAO
  • Show the problem on the whiteboard
  • Write the TDD rules on the whiteboard and as comments in the test class
Post-Retrospective, Aaron, Drew and a person whose name I don't know (sorry, I should have asked) stuck around to help come up with the problem for the next Randori.  It is a real business problem that Aaron's team is solving...

When we retrieve date ranges from Ocean, they look like this:
They must be formatted to something like:
"1/2/2001 - 3/4/2011"
Rules for edge cases:
  • Invalid string length - throw exception
  • Invalid month or day - <TBD>
  • Year not between 1700-Present + 1 - <TBD>
  • Range out of order (right side is before left side) - <TBD>