Something that happens to me every time I work with Game of Life (similarly LCD Display kata) is I end up drawing out examples. Here’s a rendition of the index card we had:Saturday, May 29, 2010
Last Weekend's Code Retreat in Boulder
Something that happens to me every time I work with Game of Life (similarly LCD Display kata) is I end up drawing out examples. Here’s a rendition of the index card we had:Friday, May 14, 2010
Developer Priorities and Guiding Principles
Recently, a pair on my current project was test-driving their solution to the current story. They had to query a service for some search results, but there were some special conditions. If the service throws an exception, present message A. If there are 0 records returned, message B. If there are over a 100 records returned, message C. Otherwise return the results themselves.
A fairly simple approach to this would be to have your controller delegate to a business class, get the results, and then inspect the results and return the appropriate answer with just a couple if’s. Opinions may differ right there. Some might like the fact that the specialized error message being displayed is “in the presentation tier”. Others might say, “why is your controller making choices like that?” And others might say, “if..else?yuck”.
Well lets use our priorities to figure out what we’re going to do. First, be test-driven. We should first and foremost be delivering a testable and tested solution. To me, it wasn’t even an option to just return that result set past the controller to the view and code the decision (aka logic) of displaying results vs. error message and what error message in the UI proper. At least in our environment (JSPs & WebLogic), that’s not testable.
Next priority, remove duplication. I’m not going to get into the purity discussion of whether you write the duplicate logic first and then refactor it vs. write the first case then refactor it at the start of the second case vs. “see it coming” and put the first case in the right place (or so we hope). In fact, in the case I’m referring to, we did the latter, but right behind this feature is another feature to do the same thing (notably with the exact same error conditions) from another angle. The second feature will have a different controller, but will be able to reuse the same business class. Anyway, we felt justified in that decision.
Back to the duplication. In order to avoid duplication, the suggestion was to push the logic of analyzing the result set to the business class, where in the special cases we’ll throw an exception with the appropriate message. Now maybe some of you are reacting like this pair did to the suggestion 1) is no results really an error? and 2) it makes me itch that we’re pushing the message Strings into the business tier. My response... I agree, but... I consider the first 2 priorities to be much more important than this itch I have. a) it’s in one place, so when the itch festers, we can fix it for both cases quickly. b) it’s tested, so when the itch festers, we can fix it safely.
In fact, in this case, both cases will have BDD tests on them while the business class will be fully TDD’d.
My point: have a bias towards action and use your development priorities as a guide.
My opinion: 1) testability 2) remove duplication.
Tuesday, January 12, 2010
Application Servers and Test-Driven Development
If you are considering tying your next project to an application server, you should seriously consider the consequences of this. What are you really after? Why do you think this is a good idea?
More than likely there are a handful of alternatives to all of your concerns. And if you were to pursue these alternatives, you will greatly improve the productivity of your team.
If you are a member of such a team where you have little to do with the decision to run under an application server, I will also make some suggestions on how to work around the server more effectively.
Background
I am a very strong believer that being test-driven is excellent start towards generally improving your productivity. I am also a believer in being story-test-driven, however that’ll be a discussion for another day. When I say “test-driven”, I am specifically referring to the red-green-refactor mantra of TDD. With respect to application servers, this does not include JunitEE and/or Cactus style testing. It’s simply not practical to write a test, compile it, build an ear, deploy it, and run your test to see it fail. On my current project, the average round trip to make this happen once is about 30 minutes. In the TDD circle of life, generally speaking, I want this cycle to be less than 5 seconds (once the test is written).
There are many reasons to be test-driven in your development. Writing tests first ensures your code is testable. Writing tests first clearly influences your design. Writing tests first definitely helps you minimize over-engineering your solution (which also saves you a lot of time). And the left over artifact of tests helps you avoid unintentional breaks from future enhancement and from refactoring. The tests support refactoring, which in turn keeps you from suffering code rot. And code rot might not kill your project instantly, but it will kill morale. There are many other reasons as well, but I’d recommend you read Test Driven Development by Kent Beck, Refactoring by Martin Fowler, and Clean Code by Robert Martin for that. As for app server development and test-driven strategies, I would strongly recommend you read J2EE Development without EJB by Rod Johnson.
Now if you do happen to have an application server, you need to consciously work to architect around it in order to be able to effectively test-drive your code. Things to consider: First, minimize your dependencies on the app server. Regardless of what front-end framework you use, keep the front-end extremely thin and light. You can certainly use JavaScript on your client, because you can unit test JavaScript with any of a handful of frameworks, none of which require you to be running the app server to run your tests. By thin and light I’m referring to JSPs, JPFs, Actions, etc. You want little to no logic in these files. Utilize some form of MVC here to maintain a good separation of concerns. If you keep nothing but simple mappings from domain/model objects to view objects and otherwise just make simple calls to the POJOs just beyond the application server, then you can keep the top-most level of your POJO model focused on the behaviors required by the application. You can easily TDD your way from there.
Just a thought: I recommend making it a goal of yours to start up the application server as few times as possible every iteration. I’m even thinking about keeping a metric for this, because I’m sure it will be directly correlated with story cycle time.
I hope this could help frame your dealings with an application server with a little bit of stategic thinking as well as help make your testing strategy more effective.
May all your tests run green.
Sunday, July 12, 2009
Top Down
I’ve been following a top-down approach to programming for years. I feel like it is the best approach to not over-engineering things. Along with ATDD and TDD, it’s a very methodical, disciplined approach. It’s also customer-centric, since by starting with an acceptance test, you’re focusing on the behavior the customer wants.
At this weekend’s #coderetreat (http://coderetreat.ning.com/, July 2009,
With cell being bottom-up (or inside out), you start with a cell and TDD the behaviors of life and death for the cell first. Now for a kata, that’s fine, because you can only do so much in 1 hour before the next iteration.
I was looking to approach the problem as an application however, a craft I’m always interested in honing, I so went straight to grid. That’s not necessarily the best name, but from this perspective, my pair and I started with questions like “what will the user need to see first?” “OK, a grid and then the user will need to set some initial cells to alive.” And so on. It should be relatively obvious, that the design from this approach will emerge quite differently.
In the past, I’ve worked with FitNesse and more recently with easyb. Both of which could do the trick of ATDD’ing the grid, but Jeff “Cheezy” Morgan introduced us to the new and improved JBehave at #coderetreat. JBehave has a super short setup time and actually runs seamlessly via the JUnit runner. So we ATDD’d our grid with in the afternoon with JBehave by defining the behaviors the user would require. Such as:
Given I have a grid
And I select some cell at 2 and 4 to be alive
And I select some cell at 3 and 3 to be alive
And I select some cell at 3 and 4 to be alive
When I evolve
Then the cell at 3 and 3 is alive
And the cell at 2 and 5 is alive
And I’m excited to do more with JBehave.
So I’m actually advocating first and foremost attending #coderetreat and using a kata-based approach to honing your craftsmanship skills. Second, I’m recommending trying to approach things very consciously from the customer’s perspective and in a way that will lead quickly to executable software, specifically top-down. Use your ATDD framework of choice (even XUnit), define a behavior of the application, then TDD the necessary units to deliver that behavior… rinse… repeat.
Saturday, April 4, 2009
Don’t Get Burned
I believe that sprint burndowns are a crutch. You should be aware of their misuse and you should figure out what you can do to move beyond them.
Like crutches, a sprint burndown can be useful to get you on your feet. Their intention is to help you see where you are with respect to the stories estimated during sprint planning.
If you feel you /need/ a sprint burndown, then I’d ask why? Do the current stories in flight and done so far not tell you where you are? If not, then that’s the thing I’m saying you should be looking into and fixing. Perhaps your stories are too big, so they’re in progress for 5+ days and you want to know if it’s going to be 4 days or 6 days? Perhaps the team is not communicating enough? Is there a high percentage of the team working on each story (especially larger stories)? Are there at least a few team or partial team meetings around the design of each story (and I don’t mean during planning) as well as around design changes discovered? If not, why not? Would that help communicate the status of the story?
If your team is healthy, then you should be regularly experimenting with process improvements. Try removing the burndown. Retrospect on what was missing without it. Perhaps bring it back and strive to fix some of the other issues as well. Then try removing it again when you feel the communication or whatever has improved. Ultimately though, planning (and tracking of the plan) is waste, plain and simple, and we should strive to minimize it.
That’s all presuming you’re using your burndown properly in the first place. Here are a few things to beware to never do even if you do keep a burndown.
Don’t let your burndown manage you. Just because 7 of 10 tasks are done, remember the story is /not done/ and so it is building inventory (i.e. useless to the customer) until the story is done. At the end of the sprint, it’s a binary done vs. not done.
Don’t get actual hours confused with ideal hours. No one should even begin to think that because you have x engineers for n days at approximately j hours per day that you should be able to deliver x * n * j hours of work this sprint. Fred Brooks told us years ago, “the man-month as a unit for measuring the size of a job is a dangerous and deceptive myth”. I believe the context fits here.
Yesterday’s weather relates to velocity, which is story estimates not task estimates. This is not a precise number. We’re talking about estimates here. Estimates are not precise and to think that they are is bad for business. If you want things to be more precise, then shorten your sprint length and go from what’s been delivered. That’s precise, because it’s done.
Don’t let the tasks manage you. The next healthy thing to do after eliminating the sprint burndown is eliminating task breakdowns altogether, but that’s another topic. Just leave it to say that because you have tasks from sprint planning, don’t just each grab your tasks and go to your cubes and work on them. It’s far more effective to have a pair (or more) tackle the story as a team. We want to /encourage/ communication.
And this may sound obvious, but trust me, it doesn’t always happen. If a task on the board is no longer relevant, remove it. If something else must be done for the story to be done, add it. If you see a refactoring to do while working on the story, do it.
Now that’s all about sprint burndowns. Release burndowns can be a different story, however, but again a future topic.
