TDD Training Difficulties

Brian Marrick explains the difficulties in trying to convince developers of TDD goodness. His first approach is to dive into some of their existing code:

This works maybe a quarter of the time. When it does, it’s the best: it shows the watchers exactly what they’ll be doing. The usual reason it fails is that the code wasn’t written test-first, so it’s hard to do anything without instantiating eighteen gazillion objects. A team has to learn to deal with that eventually, but dealing with it as the very first thing really drains the appeal out of an introduction.

Next he tries just starting over showing how the application could have been developed test-first:

I don’t know about you, but when I’m starting to build a new app, I often spend a lot of time thrashing around, trying to find a good working division of responsibilities into classes. Eventually things settle down to the point where adding new features isn’t an Adventure in Reconceptualizing, but instead becomes what it should be: fairly straightforward. I’ve gotten more-or-less used to the turmoil (though I still wish I were smarter or more experienced). The problem is that it makes me look like a complete idiot to watchers. Worse: they may not blame me. They may blame the technique, decide it’s stupid.

And the other issue is:

They look at how much we’ve accomplished in an hour or two, extrapolate that to the size of the existing code base, realize they have a long slog ahead of them, and turn off emotionally because they were hoping for some quick ladder out of a hole years in the digging.

My own approaches have yielded similar results. Last time I ran a one day training seminar on TDD I used Bob Martin’s bowling kata as the central TDD example and some smaller lab examples. For a few people this was compelling, but for many it was, “How does this apply to me day to day writing DAOs, JSF, and portlets?”

I backed that up on my team with a simple requirement. You will write tests and the coverage on your project should be at least 70-80%. I didn’t enforce test-first, but I strongly encouraged it. Over time this worked on my team. Across the other two development groups it was only partially successful.

My current approach is to write up a seminar with labs on doing TDD with JSF which is the point I hear most cited by my staff as the difficult part of doing TDD. Many of them are quickly lured into constant checking that their JSF backing beans do something in a browser. Unfortunately doing TDD with JSF is a bit painful so I haven’t completed that exercise yet.

For many developers dealing with frameworks not designed around being testable just adds too much of a burden to adopting the TDD practice. The rule now is newer frameworks tend to have testing backed because open source developers are generally fans of TDD. Ruby on Rails is a prime example and Wicket and Tapestry in java even has a built in test packages.

Time and commitment have worked well in my shop. Giving people the time to get comfortable and understand the benefits of TDD while gently prodding them all along the way has worked even if it took more than a year to accomplish. As more frameworks, libraries, and applications are built test-first by default–developers will start practicing TDD by default.

Jar Jar Standup Parody

Scrum Master Jar Jar: “Meesah wanna know, What did yousa do yesterday?”

Software Maestro

This parody isn’t too far from a really badly run standup. I’m sure some of these happen out there, and I’m sure some developers despise meetings so much they’d hate even a well run standup.

One-on-Ones In A Single Day

Turns out for me Wednesdays are a good day for one-on-ones. Until recently I had been running weekly one-on-ones with my ten or so direct reports across Wednesday and Thursday afternoons.

One-on-ones have really improved my relationship with my employees and vice versa. Problems are detected and corrected sooner, even really quiet team members get and give feedback at least once a week, and there’s a regular opportunity for coaching.

To be effective you need to fiercely defend your times for one-on-ones. During the meetings even the ringing phone goes unanswered. I don’t even glance at it to see who’s calling. If it’s the CIO with a fire to fight they’ll come down and pull me out of my office.

Two afternoons in the middle of the week turn out to be a tempting target for almost any other manager to schedule competing meetings. There’s an assumption I can re-schedule my one-on-ones since they’re only 30 minute meetings with employees. After 18 months of fighting this reality and having to re-arrange at least two meetings a week because of my schedule, I got a better idea.

Why not just schedule all my one-on-ones for a single day? The idea was appealing on several fronts:

  • It’s easier to defend a single day on your schedule rather than defending two afternoons.
  • It frees up larger strategic chunks of time on the other 4 days of the week.
  • Some of my staff start fairly early in the morning so scheduling a one-on-one at 8:00 AM is feasible.

Barely into implementation now I’m realizing unanticipated benefits:

  • I do a better job prepping for one-on-ones. You only need to prep for about 2-3 minutes per employee to jot down things you want to cover, but when the sessions were in the afternoon I often tried to do that during lunch. Now I pull down my one-on-one folders and start prepping first thing Wednesday morning.
  • I get a better sense of where my whole team is. By compressing all the one-on-ones I get an insight into what the general mood of the team is especially about business issues that impact the company as a whole and how they’re handling them.
  • My follow-up on action items is better. Fairly regularly some action item comes out of a one-on-one. Unfortunately when I mixed and matched one-on-ones with regular meetings I’d be dashing around and often I wouldn’t get around to looking at the notes and trying to do follow-up until Friday. Now I’m getting to those follow-up items on Wednesday or early Thursday morning. Faster feedback loops.
  • Selfishly, I get a sense of accomplishment. Going home at the end of the day having heard and talked to all of your employees gets me a little bit of a charge as a manager.

My results may differ in a few months but so far I’ve been able to defend my Wednesdays and achieve a better outcome for my one-on-ones.

Give Your Developers IDE Choice

I shuddered reading this post:

After months of using Eclipse, of being forced to use Eclipse, I decided I just can’t continue down this path any longer. Like a burglar in the dead of night, or a drug smuggler on the border, I committed a most sinful and most treacherous act — I installed IntelliJ IDEA to continue with day to day Java development. In the context of the company I work for, this is tantamount to lying on your resume or sexual harassment. It’s big.

IDE choice shouldn’t be grounds for a disciplinary action. An IDE is just a tool, and for pretty much any java project you can use:

  • Eclipse
  • Netbeans
  • IntelliJ IDEA
  • JDeveloper

Forced standardization might make sense when you say make a decision to use Oracle over SQL Server for the database, but for an IDE you can use any of the above tools with no real additional costs. IntelliJ IDEA does have a nominal $250-$500 cost, but I find that not to be much of a barrier. Some developers including myself regularly switch between IDEs to take advantage of different features or plugins. I spend most of my time in IDEA, but occasionally I drop into IBM’s Eclipse based RAD. Other developers might jump from Eclipse to Netbeans to do some profiling.

One of the fatal issues that leads to things like forced IDE standardization is when you don’t have a fully automated build. If you can’t run ant, maven, or even rake from the command line, no IDE, you’re dead. This tends to lead to developers who can only build from within the IDE. Next comes ‘works on my machine’ problems. Then to further reinforce the bad decision to become completely reliant on an IDE you force all developers to use it all the time.

Automated builds avoid IDE lock-in.

Then there’s the shops that believe everything must be standardized. Avoid these standardization-happy shops.

Comment Driven Design

Jef Raskin suggests comments are more important that code (via a link from Raganwald). Like test first design, you should try out comment first design:

A competent programmer who has learned the documentation-first style will sometimes think of a solution in terms of code, write that first, and then document, or will apply a mixed strategy—especially when no convoluted algorithm design is involved. This should not be discouraged so long as the programmer generally adheres to (and sincerely supports) the documentation-first approach.

— Jef Raskin

I actually remember working this way long ago in my perl days and finding it a reasonable way to get started. It’s perl so generally you’re not writing a large application all at once so outlining some of the design with comments and then beginning to build functions worked for me as an approach and as a bonus I got a decent level of documentation for my perl scripts.

Javadoc was also a great find as I migrated into Java. Here you could have generated HTML comments all inline with the code. This used to be pitched as a major advantage over Java other older languages. It’s been a long time since I saw Javadoc talked about as a major feature of the language anymore.

Gradually I left comments behind except when documenting a tricky design decision or a hack that was left in the code for now. I use it still fairly extensively when attempting to add a bug fix or enhancement to some legacy code base so at least future maintenance programmers can have an idea of what I was fixing.

With TDD driving my designs I found more readable code more compelling than any sort comments. I like Ken Pugh’s concept of ‘extreme readability’ from Prefactoring. The idea is the code is so much like the business user’s language that they could review the code and pick up the meaning. At least that’s the goal. Jef Raskin argues that while this idea from XP is a step in the right direction:

When programmers speak of “self-documenting code,” they mean that you should use techniques such as clear and understandable variable names. Instead of n or count, it is better to use a readable, self-explanatory name such as numberOfApricotsPickedToDate. This is a minimalist’s documentation. Nonetheless, it helps—the use of explanatory names, whether of variables, modules, objects, or programs, should be encouraged.

Comments still need to come first because they can’t explain the why of a design decision. His example here is a comment about why an algorithm was chosen:

:Comment: A binary search turned out to be slower than the Boyer-Moore algorithm for the data sets of interest, thus we have used the more complex, but faster method even though this problem does not at first seem amenable to a string search technique. :End Comment

I wonder if this isn’t a straw man type argument. Obviously comments on why a certain algorithm was chosen would be helpful and a good idea for any developer to include. Otherwise they either get lost or end up a design document people are unlikely to read.

It’s a very short article so he doesn’t spend much time with the issues around comments as documentation such as when they get out of sync with the code. There’s no talk of tests as executable documentation.

If one were actually to take a comment driven design approach I can’t see how you’d be able to write useful comments about design decisions. You have to actually write tests and code to make any reasonable comment about why a design was chosen. And then how are you doing document first? Does your comment look like:

// A binary search is used here for better performance.
public String findShortestNode() {

Then doing a few cycles of writing tests and refactoring the code you update it to:

/**
 * A binary search turned out to be slower than
 * the Boyer-Moore algorithm for the data 
 * sets of interest, thus we have used the more
 * complex, but faster method even though 
 * this problem does not at first seem amenable
 * to a string search technique.
 */
public String findShortestNode() {

I think I’ll just keep adding the rare comment to explain why when I need it rather than starting out comment first.