XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Mastering TDD with Deliberate Practice

Friday, June 11th, 2010

When I start and finish my 3 Day TDD Workshop, I make it clear to the participants that they will have to deliberately practice, on small pet projects or toy code, in a safe-environment ( in-the-nets, if you will), every single day, for a few months (if not years), to get really good at TDD. Deliberately practice on their design, testing, breaking-user-needs-down, pairing, and many other skills using TDD before they can use TDD for prime time.

However, post the workshop, the participants are very excited and they ignore my humble advice. Next day they go back to work and start applying TDD on their production code. While this might look like a good thing (also making managers super happy too.) Over the years, I’ve realized that this pattern is actually destructive. Without the required amount of practice, the excitement soon dies out. And developers start falling back to old habits. Many times leaving a total mess behind.

I was surprised to see very few companies or teams continue and build on these practices, while 80% of them would only use parts of it and fall back. Every time I went back to a company and saw this, I would be very depressed. So I studied what the 20% did, which the 80% did not.

  • Were the 20% way smatter or talented than the 80%?
  • Did the 20% have better management support, less delivery pressure compared to the 80%?
  • Or the 20% worked on simpler projects with no legacy code and so on?

What I found was the 20% quickly realized that they did not have enough skill to apply TDD on their projects. So they:

1. Watched Screen-casts: Watched experts do TDD on real projects. Good starting point: Let’s play TDD by James Shores or this stackoverflow answers

2. Open Source Projects: Studied and gradually started contributing small patches to open source projects, which used TDD. JUnitCucumberJBehaveFitFitNesse, etc. are all great examples.

3. Small Pet Projects: Started TDDing small pet projects. Gradually practiced in a safer environment and once they acquired enough skill and confidence, then they start applying TDD on their production projects.

In addition to practicing on their pet projects, on their own, they also took 2 hrs every week (on a fixed day of the week), as a whole team, to practice Test-Driving (TDDing) the same problem. During these social-learning sessions, they practiced Pair programming too.

Logistics: Before the meeting, one of the team member sent out the problem to everyone. On practice day, the whole team gathered in a conference room/team area, picked their pairs, set aside 90 mins to TDD the problem. After 90 mins, few pairs did a quick code walk-thru and explain their solution with important decisions they made during the session. Followed by an open discussion. [I also recommend everyone checks-in their code in some common repository, so it can be used for reference by others.]

Sample Problems: Next big question is, what problems do we use for Test Driving?

Usually I recommend starting with simple programs like:

  • Games – Tic-Tac-Toe, Snakes and Ladders, or any other board game.
  • Utility Programs – Convert Roman Numerals to Decimals, Diff 2 files, IP to Country Mapping, etc

Once they practiced enough with simple programs, then they would take some large design problems from DesignFest and try to TDD them. The beauty of these problems is, they are quite big, can take up-to a week to finish it completely. Now we are talking something semi-real world, where

  • We have limited time to solve/program a complex problem, which needs to be simplified.
  • Try to find a relevant System Metaphor that can help you visualize the design
  • Do a quick and dirty, low-fi Interaction Design to understand how the user will use this
  • Identify and prioritize the crux/essence of the problem, figure out what is the most important, what will give us fastest feedback
  • Further thin-slice the identified piece of functionality and
  • Then try TDDing it.

This truly helped them get better at:

4. Code Smells Poster: Created a big poster with all the code smells listed on it. Paste the poster in their team area. Every time anyone from the team found a code smell in their project, that person gets up and adds a dot next to the code smell. This makes everyone more sensitive to these smells and increases awareness by making things visible. (Simple game mechanics.)

5. Refactoring Fest: Picked one of the pungent code smell from their code, and organized a RefactoringFest. Meet as a group (once a month.) Developers pair with each other and everyone tries to refactor the same code on their project to eliminate the specific code smell. [Make it clear that the code will not be checked-in after refactoring. Its a learning exercise and we need a safe environment where people don’t fear touching code. Also if you need some real world code snippets to try refactoring, check out my refactoring teasers.]

6. Blog/Diary: Started writing a blog/diary to capture their learnings and list of issue that got in their way of applying TDD on their project. Writing things down really helped them internalize their learning. [Many times when I’m stuck with a problem, I start writing things down, and the answer becomes obvious to me.]

7. Form a Book Club: As a group, they picked any TDD related book of their choice. Then they decided on a chapter and met over lunch once every week. Everyone came to the meeting after having read that chapter. They used the meeting time to highlight the key-takeaways, debate on the subject and if possible demonstrate it via code.

8. Hands-on Geek-Conference: They participated in a geek conference like Code Retreat, CITCon or Simple Design and Test Conference where they got to meet other practitioners and experts. Got an opportunity to pair with them and learn from their experience plus share your own experience. [Stop wasting your time on stupid marketing conferences.]

9. Teach: They taught a course on Unit Testing or Design Principles at an induction program for new employees or at a local user group. [Teaching is the best way of learning.]

Deliberately practicing this way for a few years to really appreciate the depth and benefit of TDD.

What’s Cooking in Software Development

Friday, May 29th, 2009

Why do some authors call their tutorials as Cook books?

Its a collection of guidelines (recipes) to use the software. Very similar to cookbooks or recipe books.

Cooking has been used a metaphor/analogy for software development for many decades now. Some people have even compared Developers to Chefs, [poor] Analysts to Waiters and so on.

I find a very close resemblance between the way I cook food and the way I build software.

  • Both an very much an iterative and incremental process. Big bang approaches don’t work.
  • Very heavy focus on feedback and testing (tasting, smelling, feeling the texture, etc) early on and continuously throughout. We don’t cook the whole meal and then check it. The whole cooking process if very feedback driven.
  • Like Software, each meal has many edible food items (features) in it. Each food item has basic ingredients (that fills your stomach)[skeleton; must-have-part of the feature], ingredients that give the taste, color & meaning to the food and ingredients that decorates the food [esthetics]. We prioritize and thin slice to get early feedback and to take baby steps.
  • Like in software, fresh ingredients [new feature ideas] are more healthy and sustainable.
  • Cooking is an art. You get better at it by practicing it. There are no crash courses that can make you a master cook.
  • Cooking has some fundamental underlying principles that can be applied to different styles of cooking and to different cuisines. Similarly in software we have different schools of thoughts and different frameworks/technologies where those fundamental principles can be applied.
  • We have lots of recipe books for cooking. 2 different cooks can take the same recipe and come up with quite different food (taste, odor, color, texture, appeal, etc). A good cook (someone with quality experience) knows how to take a recipe and make wonderful food out of it. Other get caught up in the recipe. They miss the whole point of cooking and enjoying food.
  • Efficiency can vary drastically between a good cook and a bad cook. A good cook can deliver tasty food up to 10 times faster than a lousy cook.
  • Cooking needs passion and risk taking attitude. A passionate cook, willing to try something new, can get very creative with cooking. Can deliver great results with limited resources. Someone lacking the passion will not deliver any edible food, even if they are give all the resources in the world.
  • Cooking has a creative, experimental side to it. Mixing different styles of cooking can leading to wonderful results.
  • Cooking is a constant learning and exploratory process. This is what adds all the fun to cooking. Not cooking the same old stuff by reading the manual.
  • In cooking, there are guidelines no rules. One with discipline and one who has internalized the guidelines can cook far better than the one stuck with the rules and processes.
  • “Many cooks spoil the broth”. You can’t violate Mythical Man Month.

Also if we broaden the analogy to Restaurant business, we can see some other interesting aspects.

Thin Slice

Sunday, May 3rd, 2009

For a given feature, we can come up with multiple thin-slices which can be incrementally (sequentially) built.

Thin Slice is the simplest possible functional, usable, end to end slice of functionality.

Thin Slicing a feature is not a new concept. Generally development teams consider the simple happy path scenario as the first thin slice. The alternative flows are considered as subsequent slices. Today when I think of a thin slice, its slightly more sophisticated than just considering happy path and alternative paths.

Let me explain with an example: Lets consider we are building a web app and we need a feature which allows the user to upload their profile picture.

We can come up with the following thin slices:

  • User can upload any photo (predefined set of image format) – won’t look good coz the image size can vary and hence where ever its displayed won’t align well. Might not have AJAX support (depends on what is simple and quick to do). All the bells and whistles are pushed for later.
  • Build an image scaling facility so that we can reduce the image resolution and hence its size
  • Provide an image cropping facility so that users can crop their profile images
  • Instead of uploading an image from my disk, provide a facility to pull it from the web. The user provides the URL
  • and so on….

Each slice is functional (end to end, we are not just doing the UI or backend bit). This is great for internal feedback. Might not be good enough for a public release. Esp. with just the first slice. In some sense we are incrementally add more power to the feature with each thin slice. From another perspective it feels like we are iterating over the feature and refining the feature as we go along. In either case, We build the feature by adding one by one the thin slice, till the point we feel we can release this feature. Post release we can continue to add more slices.

It is also possible to come up with thin slices which are perfectly releasable. Lets take the same example and see how we could come up with thin slices which are releasable.

  • User can upload a photo (predefined set of image format + clear message showing the expected size and resolution). Any image which does not qualify this criteria is rejected.
  • Knock off the resolution constraint and build image scaling facility so that we can reduce the image resolution and hence its size
  • Knock off the image size constraint and provide an image cropping facility so that users can crop their images to fit the right size
  • And so on…

Check out another example of Thin Slicing from the Protest Project.

Please note that the concept of thin slice is also applicable at a much broader scope than just at a feature level. For Ex: On a given project we use the same concept to plan our small & frequent releases. At a portfolio level we apply the same principle to break projects into smaller loosely coupled projects and then prioritize them.

    Licensed under
Creative Commons License