Archive for November, 2009

Nov
09
By: Adam Sroka
11/9/09 7:16 pm UTC
Topic: No Tags

On Agile teams no one owns anything. The team is collectively responsible for what they create.

Agile teams are “cross-functional.” They are “Whole Teams” consisting of a variety of experts with different skill sets.

On the surface it seems like there is an inherent contradiction between the above ideas. At least, there is a conflict.

I am an expert and I want to do the things for which I am an expert. There are other experts and they can do the things for which they are experts. Yet I don’t own any of the work, and somehow I am responsible for what other people do.

The Expertise Exists on the Team

I need to let go of the notion that I am the expert. There are simply a number of things that need to get done, and I should do the next one.  The next one might not be the one that is most comfortable for me.

I think that I am a rock star programmer. I think that I am a lousy interface designer. Yet if the next thing to do is to create an interface then my job is to do that.

But, I don’t know how to do it! Good. It’s time for me to learn. Does someone on my team know how? Maybe I should ask them.

Cross-functional doesn’t mean that someone knows how. Cross-functional means that anyone can do it, and anyone can ask for (and receive) help.

There are lots of benefits to this:

    • Everyone learns the system.
    • Everyone learns how to make the system better.
    • Everyone learns how to ask for help.
    • Everyone learns to help.
    • Everyone learns.


      Nov
      07
      By: Adam Sroka
      11/7/09 10:53 pm UTC
      Topic: No Tags

      Continuous Integration has hit the mainstream. Teams that haven’t the first clue about agility are using tools like CruiseControl or Hudson to automatically build their software on a central server. Unfortunately, like a lot of things by the time Continuous Integration hit the mainstream the message had been somewhat diluted.

      Continuous Integration really doesn’t have much to do with tools like CruiseControl. In fact, the earliest XP teams practiced Continuous Integration without the benefit of such a tool. They simply ran the build locally, checked in the code, moved to another machine – the “integration” machine, checked out the code there, and ran the build there. The original practice of Continuous Integration simply required that every member of the team did this frequently (Not actually “continuously”) as often as several times a day.

      Because of the tendency to conflate the tools with that original practice, I often refer to that original practice as Run it Somewhere Else which is intention revealing. Continuous Integration today is really a mixture of three important practices:

      1. Collective Ownership – the whole team owns the code. Changes that I make have an effect on the rest of the team, and I need to share them as early as possible.
      2. Run it Somewhere Else – in order to know if the code I have created integrates successfully I need to check it in, check it out somewhere else, and verify that it runs outside of my development environment.
      3. Ubiquitous Automation – this term was introduced by the Pragmatic Programmers. It means that anything which I must do again I should automate so that I am not duplicating effort. It is the practice of Ubiquitous Automation, and not Continuous Integration, that informs the need for a tool like CruiseControl.

      Why CruiseControl is Not Enough

      Just running the code with the tool is not enough. Sure, we know that the code is checked out and compiled. Hopefully, we also have some tests and running those tests will tell us if the code works. The latter is actually much more important than the former. What we need is an Informative Build.

      What is an Informative Build

      An Informative Build is a build that tells us what the state of our development is so that we can make an informed decision. We need an informative build, because otherwise Continuous Integration is just a waste of our time.

      That’s right, I said Continuous Integration is a waste of time. It is a waste of time, because simply running a build doesn’t help us unless that build can also tell us what we need to do. An Informative Build:

      1. Fails when something is wrong, letting us know that our system is broken and we must fix it.
      2. When it fails it tells us precisely why it failed so that we know what we have to do to fix it.
      3. When nothing is wrong it doesn’t fail. We shouldn’t be wasting cycles chasing down errors due to brittle tests or external dependencies.

      In order to have these qualities, our build must:

      1. Have lots of tests that thoroughly cover all of the interesting behaviors of all of the modules in our system.
      2. Have informative tests. Tests that fail only when a specific behavior is broken, don’t fail because of some external dependency, and tell us exactly what behavior is causing them to fail so that we know what to fix.
      3. Be fast. We need to be able to run it very often so that we know fairly immediately when we have a problem.

      Therefore, our tests must:

      1. Be isolated – focused on a single interesting behavior and decoupled from any dependencies.
      2. Be very, very fast – we need a lot of them, and we need them to be collectively fast. Thus, individually they must be very fast.
      3. Be comprehensive – they must exercise the behavior that they test well enough that they fail whenever it fails in whatever way it might fail.


      Nov
      06
      By: Adam Sroka
      11/6/09 6:17 pm UTC
      Topic: No Tags

      Working with dates is very common in software. The need to track dates and do calculation based on dates crosses nearly every domain. In fact, dates are such a common part of every aspect of our lives that dealing with them is second nature to most of us.

      Unfortunately, even though we are very familiar with dates, dates are complicated. Unlike numbers or strings dates are full of complicated boundaries and rules. What happens at midnight? What happens at the end of the month? What happens on a leap year? Etc. In order to build a system that uses dates we need to be aware of what happens at all of these boundaries and how our system will handle them.

      In addition, business rules that deal with dates can be complicated. They can say things like, “On the last Thursday of the month, unless that Thursday is a holiday in which case we move it to the prior Thursday, or if that Thursday falls during the blackout period in December in which case it moves to the Thursday after the blackout period ends.” Such rules are complicated enough for humans to deal with, but when you try to put them in code they can be a real headache.

      Because of these issues and others, testing business logic that deals with dates is one of the harder areas to work with. There are a few rules of thumb that will help us:

      Never use “Now” in a test

      Often times business logic involving dates is concerned with how a particular rule applies to the current time, right now. The most obvious way to deal with that is to have the method that calculates the rule call the system and get the current time.

      Unfortunately, if you do that the only way to test it is to have the test also know what now is. Then, you can perform the same calculation in the test and see if the result matches what the code produces. There are a couple of problems with this:

      1) There is a lapse in time between when the test calculates “now” and when the code under test does the same thing. If that gap falls on a boundary the test could fail.

      2) There might be multiple interesting permutations of the method you are testing. If you are tied to the current time then you can only test one permutation, and the one you are testing might only happen to be one of the interesting ones.

      Test all interesting permutations

      Testing all interesting permutations is a general rule that applies to all data types, but it is truly important for dates, because the number of interesting permutations may be high and what constitutes an interesting permutation may not be obvious or may not be the same from one calculation to the next.

      Boundaries are particularly difficult and may be easy to miss. Did you consider what happens at the end of the day? At the end of the month? At the end of the year? On a leap year? Are you looking at ranges of dates? Does the order of dates matter? Do you need to worry about different timezones? Do you need to differentiate workdays, weekends, holidays, etc?

      Pass in the date

      In order to test a number of interesting dates you need to pass them into the calculation. Thus, the method that does the calculation should never get the date for itself – whether it is “now,” or from a database, or from user input, etc. You should obtain the date at a higher level and pass it in to your calculation.

      This is an application of a principle know as Dependency Injection (aka Inversion of Control.) There are two ways to accomplish this. Either the class that calls your calculation obtains the date itself and passes it in, or the class that contains the calculation obtains the date from some collaborator that is passed to it. Let’s look at both of these:

      public class FunWithDates {
         // now is passed in from the caller
         public Date calculateSomeInterestingThing(Date now) {
            ...
         }
      }

      or:

      public class MoreFunWithDates {
         private DateCalculatorThingy dateCalc;
      
         public MoreFunWithDates(DateCalculatorThingy dateCalc) {
            this.dateCalc = dateCalc;
         }
      
         public Date calculateSomeInterestingThing() {
            Date now = this.dateCalc.now();
            ...
         }
      }

      The first approach is simpler, but the second approach defines an additional class for the responsibility of determining what date to supply. Encapsulating this responsibility may be useful for many problems that are more complex than simply knowing what the system thinks the time is here and now.

      Write the Test First

      Of course, in an Agile environment this advice is generally applicable as well. However, dates make this particularly poignant. As I already mentioned, dates are hard, and because we use them every day we are particularly familiar with how they are hard.

      It is easier to think of the ways that dates are hard than it is to speculate on a solution that would satisfy all permutations. So, encode the most interesting and representative dates in your test, one at a time, and create the simplest implementation that will make each test pass, one at a time. What you will arrive at is a solution that handles all the interesting cases you can think of, is easy to test, and is clearly documented by the tests.