James Carr | Rants and Musings of an Agile Developer

Archive for February 2010

Feb/10

28

Retrospective Rules

I’m gearing up to put together a retrospective for my team at my current client site, and I’ve been both thinking about and reading over notes from previous retrospectives I’ve either sat in or facilitated. Looking over a lot of these notes, especially from the worst ones, I’ve noticed an emerging pattern of behavior that can either make or break a retrospective. Here’s a few that I think are the most important.

  1. Retrospective Belongs to the Team

    This is possibly the most important observance I’ve noticed… retrospectives are only effective if they truely belong to the team. This means that it should only be attended by the team and only the team can pick a goal and how they’re going to follow up on them. Management shouldn’t attend the retrospective imho as they can cause interference, step in, or require metrics to be collected. Several retrospectives I participated in at my previous client had the manager constantly cut people off or tell them that the goal they’re proposing won’t work and refuse to let it be considered. These retrospectives were the most useless in my opinion and we never accomplished anything.

  2. Don’t Let It Become a Whine-fest

    Retrospecting is about inspect and adapt… about looking at our experiences over the past and using root cause analysis to find causes and how we can improve in the future. However, if there is plenty of negativity in the past, it can be easy to succumb to “crying over spilt milk” without coming up with any real solutions. And nothing is worse for a team then to spend an hour in a room listening to each other bicker without any from of constructive activity… it will leave the team feeling down rather than up. Therefore aim to keep the retrospective on track to discuss the facts and observances and put emphasis that the past is only for concrete experience to draw ideas from. Problem solving activiities should be given more focus than pouring over historical data.

  3. Activities Are Better

    I’ve sat in on hundreds of retrospectives, both with activities and without. On the outset, the no-nonsense, just talk about “what worked, what didn’t, what to improve” sounds good, simple, and to the point. However, my experience indicates these were amongst the lowest in terms of effectiveness. For starters I think it keeps people locked into a “this is a meeting” mentality and prevents thoughtful activity. Hell, one place I was at just put a word document up with headings titled “What Worked, What Didn’t Work, Action Items” in which Action Items were items the manager would enter into Rally Project Management and assign to people to work on.

    I’ve found that activities often keep people engaged. In a meeting someone can get by by sitting in front of their laptop staring at the projector, with activities they’re constantly involved and not given time to disconnect. Additionally, I find the care freeness (or even fun) of activities helps break down some subtle communication barriers and makes people feel more free to speak their minds.

  4. Pick Only One Goal

    In theory picking multiple goals sounds great right? We’ve identified all these impedments and road blocks in our team,process, or environment that really need to be addressed. Why don’t we just tackle ALL of them rather than ignore them so we can work on removing all of them? This is long the same lines of the theory that maximizing Work-in-Progress maximizes effeciency and we all know that this often fails. LIkewise, by maximizing the number of goals that you have for an iteration you run the risk of context switching too much (not to mention all the focus you’ll already have towards the work you’re doing during the iteration) that the team will lose track and quite possibly not make any headway towards any of the goals listed.

    Therefore, limit your Work-in-Progress as a team by selecting one (and only one) goal for the team to work towards during the next iteration. Maybe you’ll complete it in one day. Maybe you’ll complete it by the end of the iteration. Maybe you’ll make progress on it and discover in the next iteration that you uncovered deeper issues that need to be addressed.

  5. Follow Up

    One of my biggest mistakes I ever made as a facilitator was failing to help the team follow up on goals… I assumed you could just let the team form a goal, work out how they would accomplish it, then just let them leave the room with it to schedule into their iteration and complete. Boy was I wrong. Working towards that goal can possibly even grow future retrospective topics, or like I mentioned previously uncover more serious or deeper issues the team needs to address. Failing to follow up can leave the team with a slew of goals they never complete or superficial goals that only kick some dirt over the issue. So it’s good to recap on the goal that was formed as part of establishing historical data near the beginning of the retrospective and let it help drive new ideas or delve deeper if it wasn’t completed. Often times you can find incomplete goals correlate to the iteration… for example if it wasn’t reached because there wasn’t enough time to work on it, maybe there’s not enough slack in the iteration?

Again, out of all these, I’d have to say the most important is number one: the retrospective belongs to the team. This is an activity for the team by the team to help them inspect and adapt their process and shouldn’t be something enforced upon them or led by their manager. I ask all ScrumMasters out there to take special care if you facilitate the retrospective… in my opinion you really shouldn’t, but if there’s an absence of facilitation skills you might need to. If this is the case, remember your position… you are not a manager and therefore should not use this to dictate goals to the team. Stay as neutral as possible and at all costs do not allow yourself to become the owner of a solution, it needs to belong to the team and the team needs to make whatever needs to happen happen. If they need to schedule a task into the iteration, let them do it rather than do it for them.

Likewise, as a facilitator it is of utmost importance to remain neutral. When I facilitate teams I am on I try to refrain altogether from involvment. Also remember as facilitator it’s your job to facilitate the discussion, not drive it or offer solutions. I’ve facilitated a retrospective once where someone called on my expertese with fitnesse to help them solve a recurring fitnesse problem they were having. Sadly, I offered solutions. Looking back, I should have suggested that they come up with a goal, and if they needed help they could come seek me out when I had my developer hat on out on the floor. Further, I often find that when a facilitator from the team participates, they often drive the entire retrospective. Either their ideas lead for the rest to follow (even if they participate last) or the teams participation might fall on deaf ears. I once watched a friend of mine facilitate a retro for our team and draw out a huge value map… at each time two or three pople would say what they thought the cause was, then he’d say “well, I think it’s really this…” and write out his own idea in the map without taking into account what the team said. When I called him out on this he couldn’t believe he did that. :)

Overall, keep in mind the retrrospective is for finding solutions, not problems. Keep it on track, listen, and help guide the teams to introspect within themselves and find the solutions they need. Most importantly let them do the decision making and above all use the retrospective as their own activity to get better. :)

No tags

Been doing some fooling around with scala for a little bit tonight, and specifically been trying out the BDD framework specs. specs adds some nice stuff to mockito that makes it read like a natural language… and I like it!

Take this simple example of stubbing:

list.get(0) returns "yo"

Yep… that’s perfectly valid scala code… and totally awesome. :)

Want to verify that a method was invoked with a specific argument?

notifier.send(order) was called

And again yes, that is a real line of code pulled from one of my examples. Take a look at more here.

No tags

Feb/10

20

links for 2010-02-20

Feb/10

19

Git SVN On Windows

At work we use svn and lately I’ve been trying git svn to maintain a local git repository that I can push to the svn server. So far, I love it! The best feature is being able to use git stash to “stash away” the current dirty workspace, work on something (say a defect), commit and then call git stash pop to return to what I was working on.

Setup is quite easy… on windows, you need to install Cygwin and under devel package select git and git-svn.

Once it’s installed, just follow the following steps to get started:

  1. git svn init http://path/to/svn/project/trunk projectname
  2. cd projectname
  3. git svn fetch -rREVISION (most likely this will be git svn fetch -rHEAD
  4. git svn rebase

That’s it… all the usual git commands will work, and when you’re ready to commit just type git svn dcommit

My only worry is that I have yet to have a conflict, and I’m afraid I’ll be hosed without my usual eclipse conflict compare. :)

No tags


When it comes to working in the software industry, I think I can best sum up what a majority of developers and teams do by simply quoting Pink Floyd from the song Breathe:

Run, rabbit run
Dig that hole, forget the sun
And when at last the work is done
Don’t sit down
It’s time to dig another one

I think that verse goes quite well with what I kind of view as the default behavior of developers when they stand beneath an overwhelming amount of work that is ahead of them on a project. It’s quite easy to “hit the ground running” and work as hard and quickly as possible, kind of brute forcing their way through it. The end result can truly mean forgetting the sun and leaving all manner of holes in the codebase with a rushed, “the sky is falling” feeling continuously looming over them while working on multiple tasks at once.

Sustainable pace is very important because if you don’t adhere to it you’ll often find quality will suffer. Working nonstop will burn you out in the long run which can be seen either by silly defects or sporadic performance. Additionally, by maintaining a pace you’ll also have a better opportunity to manage your relationship with your customer and enjoy a rich communication channel with them rather than succumbing to rushed, last minute conversations over instant message in the eleventh hour with them waiting for each new deploy to “see if you fixed it” (and believe me, being in that situation can really suck).

Add slack to your iterations, estimate work before committing to it and keep your work in progress limited rather than trying to tackle 900 things at once. Only do what you’ve committed to for the iteration, and if you get everything done use the slack time to improve the environment or even improve relations with your customer by going over the existing and planned features with them. Don’t take on the next iteration’s work early, instead schedule stories to work on during slack time that can make future work simpler. :)

For long you live and high you fly
But only if you ride the tide
And balanced on the biggest wave
You race towards an early grave

No tags

Feb/10

12

Running EasyB Specs From Gradle

Although the cookbook includes an example of using the easyb ant task to run specs and produce reports, I thought I’d try my hand at writing a task to manually run easyb specifications from the commandline. Here’s the result:

task spec <<{
    ant.java(classname:'org.easyb.BehaviorRunner', fork:false,
      classpath: "${sourceSets.test.runtimeClasspath.asPath}")  {
        sourceSets.test.java.srcDirs.each { testDir ->
            testDir.eachDirRecurse { dir ->
                dir.eachFileMatch(~/.*\.specification/){spec->
                    arg(value:spec.absolutePath)
                }
            }
        }
    }
}

Now I can run “gradle spec” from the commandline to write all my easyb specs. Spock is next.

I’ll admit I’ve just recently gotten back into groovy, so I’m still kind of a noob. I keep feeling like groovy has a better way to search for file patterns recursively. :)

No tags

Over the past four years I have at various times over and over explained to my co-developers why writing tests against setters and getters is bad, dealt with the whole “metrics” argument, and quite frankly I start to get weary repeating myself every three months. :)

While I was driving into work today, I started thinking about the subject again as I’ve been debating a topic yet again recently that I quite honestly don’t think it warrants any debate and decided that since I haven’t written any blog posts on the subject, I should. So ahead I will describe why test driving setters and getters isn’t only a waste of time, but it is also considered harmful to your design as well!

First off, I’ll point out why I find it a waste of time. I’ve seen developers labor furiously in the past to verify that a behavior that at the simplest is already done for them by their IDE. If your IDE has generated them for you, and you decide to write tests against it, you’re first of all bullshitting yourself that you’re practicing TDD, because you’re really writing tests after the fact. Secondly, what the frak are you testing? That the developers of intelliJ/eclipse/textmate/whatever wrote their setter/getter generation code correctly?

Another myth is that, while the above argument is correct, the setter/getter “might” have some behavior in it, or if you don’t write a test against it and someone goes in and modifies the behavior, there will be no “tests” to catch it. Now, I can’t say for you, but I don’t write tests to “catch bugs”, I do it both to prevent them and to ensure my design is sound. Secondly, I also adhere to concepts like YAGNI (You Ain’t Gonna Need It) and creating “The Simplest Thing That Can Possibly Work.” If I’m going to change the behavior of my setters or getters, I’ll write a test for that behavior before I change it. If you’re trying to prevent developers from being sneaky, well then you have team issues that you need to address, and I don’t think the best way to deal with those team issues is by decreeing that all setters and getters need to be tested.

These are all perfectly good reasons not to test setters and getters in my humble opinion, but now let’s get to the real reason you shouldn’t do it, and why I even considered it harmful to your design. See, when we practice Test Driven Development, there really shouldn’t be so much of an emphasis on “test” but rather on “design” (this is why I really lean toward using the term Behavior Driven Development). I’ve said this before, but let me recap.

We use tests to drive our design. Each test provides an example of functionality that we use to prove the need for the code we’re going to write to exist. With a failing test in place, we then write the code that we need to make that test pass, then on to the next. Using this iterative approach, we allow our system to take part in emergent design, proving we really do need the code we’ve written. If we wrote code we didn’t write an example for, there’s the possibility that we really don’t need that feature (or we do, we just thought too quickly and didn’t write an example). Setters and Getters should get exercised while executing these examples.

Wait, back up. “Setters and Getters should be exercised while executing these examples.” What I mean by this is that when you write a test against a feature that, let’s say returns an object, you should be doing a verification on that return value’s field to see if a value was set to the expected value, in which case in the course of that test the setter and getter get executed. The example for that specific feature proves that you need that field to hold some value.

A simple example:

@Test
public void shouldAddDiscountIfTenOrMoreItems(){
	Order order = new Order();
	order.setItems(add(10).items().thatCost(ITEM_PRICE));

	calculator.calculateDiscount(order);

	assertEquals((ITEM_PRICE*10)*0.20, order.getTotal();
}

Now in this example, we exercise various setters and getters in Order, because we need them. That’s right, because we need them… our feature that our business cares about needs them in order to work.

Now we lead ourselves to why TDD’ing setters/getters is harmful… by writing tests against setters and getters, we’re saying that we need these properties on an object, but we’re not explaining why. This is akin by starting a project by hitting the ground running and designing the database without no real understanding of how the data will be used. At the least you’ll possibly be defining objects and properties you might night use… at worst, you’ll create a design of objects that aren’t grouped within the domain correctly, which will show itself overtime when you have domain objects and services that, although they work, don’t make a lot of sense.

This is a good middle ground for people concerned with metrics. Although I think that high code coverage is a side effect and not the end goal, if you follow this practice you should achieve optimal code coverage without succumbing to wasting your time testing field names. :)

UPDATE: Pat Maddox posted a link on the TDD mailing list to an old (but rather insightful) article on why getter and setter methods are evil. I’ll have to say I agree with this quite a bit!

No tags

Wow… sometimes memories sprout up out of nowhere, and tonight while painting the kitchen I was reminded of my first programming job interview waaaay back in 2003. See I had picked up a few pamphlets at the university career fair and landed a job interview with one of the few (or was it only?) firms offering a computer science related job there. So I dressed up with a tie, made sure I made three copies of my resume on expensive ass paper, put them in a fancy leather folder and headed off to the interview with my fingers crossed.

As I sat through the interview, I went through the usual motions of answering their questions about my background, listened to their marketing talk about how great their company is, and I chatted a bit about my hobbyist programming I did in my free time. Then came the bad news…. the interviewer smiled as he mulled over my resume, and he said he noticed that I didn’t have any COBOL experience. He asked me if I had ever taken any COBOL classes at the college, and I told him no… as far as I know they don’t even have it in the curriculum anymore.

“Really?” he replied, with a slight look of shock on his face. “Well, all of our systems are written in COBOL here, so that’s what you’d be developing in. We really need someone with COBOL experience.”

“Well, I pick up languages pretty quick… I just learned python last week and was able to do all kinds of things with it… I probably wouldn’t have any problems learning COBOL and actually using it.” I replied.

He smiled. “Well, that’s great James. I’ll tell you what, I’ll talk with the rest of my staff and I’ll try and get back with you by the end of the week to let you know if you made it in.”

And I never ever heard from them again. Another guy at my university, who had made straight As in CompSci and double majored in Mathematics got hired out there the following week, so I guessed maybe I just didn’t have a high enough GPA to meet their standards. I remember wondering what was so special about the language… I looked around online and the examples I found were pretty ugly and I remember wondering if it was some kind of joke? But I did hear from the guy who got the job out there that yes… all they programmed in was COBOL.

Looking back, I’m damn happy I never got the job. A large part of my growth was working for a small start up firm and getting the chance to work with all kinds of languages as well as do a lot of reading online to self-teach myself (I didn’t have any senior developers to work with… just me at first) that led me to read books like Design Patterns, Patterns of Enterprise Application Architecture, Refactoring, and even Extreme Programming Explained as I searched for a methodology to manage our projects. With no one to turn to, I often sought help in online forums, mailing lists, and usergroups in St.Louis. I think all of that played a large part in growing as a developer and evolving my thinking.

If I had gotten that job, I probably would have done my best to excel at it… and perhaps by now I would have been promoted to the position Programmer Analyst II. :)

No tags

Yesterday evening I fooled around with gradle quite a bit, finally sitting down and taking some time to learn it as I’ve been hearing lots of good things about it. And man, I like it!

I decided to use it to build the kind of project that enterprise architects go ga-ga over: a multi module project that contains a shared module with an interface (containing JAXWS annotations), a services war module to create a service implementation, and a client implementation to call it. It was a breeze and I finished it in a couple hours.

(more…)

No tags

Feb/10

5

links for 2010-02-05

No tags

Older posts >>

Theme Design by devolux.nh2.me