in·dom·i·ta·ble
adj.   Incapable of being overcome, subdued, or vanquished; unconquerable.

16th
OCT

TDD Primer: Video

Posted by indomitablehef | Filed under TDD

From ARCast.tv, a Test-Driven Development Primer with Peter Provost. (click “Watch”)

This 5 minute video does a fantastic job of introducing and reinforcing the idea of TDD. I plan to add it to my tool belt of evangelizing tools, and make all my friends watch it with me.

8th
OCT

TDD == TFD, and WWTDDD?

Posted by indomitablehef | Filed under TDD

In recent discussions with colleagues about Test Driven Development, I was reminded of the importance of the “Driven” part of Test Driven Development. When I first heard about TDD, I naturally got excited about it. It sounds great. It’s obvious, really, once you see it. Obviously the way things should be.

But then reality sets in. Writing tests is an entirely new skill to learn, and not a particularly easy one, at that.

Think back on your first Object-Oriented development efforts. How “object oriented” were they, really? For many of us, our first attempts at OO ended up being very procedural solutions implemented in a rich object oriented programming language. In theory, we were gung-ho about OO. But we hadn’t yet transformed our way of thinking about problems into a framework that would take advantage of all the wonderful things that OO could offer.

How many of us eventually wandered off the other side of the trail? After realizing that we were stuffing square, procedural pegs into round, object oriented holes, we vowed never to make that mistake again. Every class had an interface, every object a factory, every entity an inheritance hierarchy, and we ended up with a polymorphinhericapsulatestracted mess.

TDD is much the same. It’s a new paradigm. A new world view. To really be effective at it, it must transform the way you think about software development (even in the database - but that’s a post for another day…specifically, after I’ve figured out how to do it better). I was at a conference recently (ITARC Atlanta - IASA Regional Architect’s Conference) where Scott Ambler said: “if you’re not writing tests, you’re not a professional”. Ouch. Seriously…that stings, because I know deep down that it’s true. Ouch.

My journey into TDD is far from done, and I haven’t yet earned my merit badge, at least in my own eyes. But I have learned a couple of things along the way.

1. TDD == TFD
The most important thing about TDD is that you must (absolutely must) write the test first. TDD is really TFD - Test First Development. It can be more than just “first”, but to do it well, it has to be done first. Why? If you don’t write the test first, you won’t write the test. My first two, maybe three attempts at TDD after I drank the Cool-Aid failed miserably because I did not grasp this concept. We all have time pressures (those of us that get paid to do this, anyway). When you are under pressure, and you’ve already written working software, the temptation to skip the tests (promising to come back to it later) is just too great. Under pressure, the mind looks for shortcuts, and finds them. Tests fall by the wayside, along with all your good intentions.

2. WWTDDD? (What Would Test Driven Developers Do?)
“Being TDD” is like coming to Jesus. There’s no way you can go back and atone for all the code you’ve written that doesn’t have a test. The best you can do is to start trying to do better today. If you have time to go back and write tests for something old, do it. Atone for past sins when the opportunity presents itself, but don’t wallow in guilt. But from now on, begin your day with testing. Begin every new task by writing a test. Get religion. Start by writing tests for anything new that you do, and write a test for any bug in existing code that you have to go back and fix.

I have these diagrams posted on either side of the door to my kyoobickle:

10 Ways to Improve Your Code - Neal Ford (www.nealford.com)

10 Ways to Improve Your Code - Neal Ford (www.nealford.com)

tddsteps.jpg

Introduction to Test Driven Design (TDD) - Scott Ambler (agiledata.org)

5th

Acceptance Tests

Posted by indomitablehef | Filed under Agile

This post is all “out of order”, since I should probably talk about User Stories first, but I feel guilty for not posting often enough, and when I have something to post, I reckon I’d better just throw it out there…so here goes.

Read up on User stories here: http://en.wikipedia.org/wiki/User_story

For every User Story, we should have one or more acceptance tests. I use index cards, (4×6, but I wish I had stuck with 3×5). I write the user story, title, number, and effort estimate (in story points) on the front of the card. I write the acceptance tests on the back of the cards. Like everything else along the way towards agile development, writing user stories and acceptance tests is a growing process. Our first pass at acceptance tests for our stories was woefully inadequate, but it got us used to the idea and got us thinking in the right direction - believing in the principle.

Now, we’re working on getting better at it -writing “good” acceptance tests. Remember that user stories are written by users. So are acceptance tests. Still, everyone will need coaching, and sometimes hand-holding. Take it slow, be a salesman, not a tyrant. (something I have to remind myself of)

Acceptance Tests
Think of them as a script that you will eventually use to evaluate whether a story is complete. Imagine a scenario where you write the story on the front of the card and hand it to the developer. When the developer is done, he returns the card to you. You then flip it over and proceed through the acceptance tests, and if all the conditions you specified are satisfied, then the story is done.

Acceptance tests are “black box”: that is, they focus on expected results or observable behavior. Avoid design discussions whenever possible.

An example:

Story: Add Patient Health Risk
The Clinician selects a drug from the patient’s list of drugs, and enters a Health Risk related to that drug. He selects Risk category/subcategory from drop-down lists (see cat/sub-cat list), and selects severity (severe, critical, major, moderate, minor) and status (identified, opened, closed-resolved, closed-unresolved, pending) , also from drop-down lists. He can enter notes for the HR and Sub-Category specific details (see list of detail fields for Health Risk sub-categories).

Acceptance Tests
1. A Clinician can view a patient, select a medication, and choose to add a Health Risk specific to that medication.
2. A Clinician can enter category/subcategory/status/severity/notes/sub-cat-details for the Health Risk and save it.
3. A Clinician can view a list of Health Risks for a patient and see, at a glance: Drug/Cat/SubCat/Severity/IdentifiedDate, Status. List should be able to “group by” the available columns and filter by status/severity combinations, as well as Identified date ranges.
4. The system automatically records status change dates and user info whenever the status of the Health Risk changes. Status history info is available on the Health Risk detail view.
5. The system will not allow the Clinician to add multiple Health Risks for the same drug with the same category/subcategory.

Things to notice:

  • #3, #4, and #5 are not specified in the original story. These are the kind of undiscovered requirements we hope to uncover while writing acceptance tests.
  • #4 is packed full of undiscovered requirements:
    • It mentions a “Health Risk Detail View” not discussed in the story – a requirement tucked into a prepositional phrase at the end of an acceptance test.
    • “whenever the status of a Health Risk changes” – when does the status change? At the very least, this probably means that the user can edit the Health Risk, but this hasn’t been mentioned yet, either in the story or the acceptance tests. It could mean more: are we expecting the status to change automatically based on some event? Better find out now.

Some questions to kick start the brain when writing acceptance tests:

  • I will know this story is complete when:
  • I will be satisfied that this is done when I can:
  • For this to be complete, the solution must be…
  • For this to be complete, the solution must have the following qualities:
  • When complete, the solution must meet the following conditions:
  • When complete, the solution must conform to the following standards: