Adam Sroka
 
View LinkedIn profileView Adam Sroka's LinkedIn profile

Nov
30
By: Adam Sroka
11/30/09 1:21 am UTC
Topic: No Tags

Agile teams have no leaders, because everyone on an Agile team is a leader. However, leadership is still important. So, how does leadership work if everyone is a leader? Here are my rules:

1) If something needs to be done, do it. Do it very, very well.

2) Never do anything by yourself. Always ask for help. Always give help.

3) Don’t delegate, cooperate. Never tell anyone to do anything that you can do for yourself.

So who is really in charge? The customer is. The customer knows what she wants and what she is willing to pay for. The team must deliver that.

The team gets to decide how to meet the customer’s needs. You won’t always agree. You have to work it out.

Remember that the right people showed up. You will solve the problem to the best of your ability and so will your teammates. Telling them how is counterproductive. If you know how then do it yourself, but involve them.

If you work this way everyone has an opportunity to succeed, to learn, and to grow.



Nov
18
By: Adam Sroka
11/18/09 10:13 pm UTC
Topic: No Tags

Good unit tests are:

Fast – they run in no more than a few milliseconds on typical hardware

Isolated – they remove any dependencies using mocks which verify the way the dependencies are called and stub the return value.

Repeatable – they have no dependence on external state and can be run over-and-over with the same results (Unless the code changes.)

Examples – they demonstrate the way that the code is intended to be used and thus enable Coding By Intention (If you write them first.)

(note: due respect to the author of FIRST but I prefer my version.)



Nov
12
By: Adam Sroka
11/12/09 5:59 pm UTC
Topic: No Tags

Conventional wisdom says that literal values in code are bad and should be replaced with constant fields. The usual justification is that when you need to change the value it is easier to change the value of the constant than to change the literal in the various places where it appears. This avoids the real issue: why is the value appearing in multiple places?

Constants are a deodorant. Rather than using a literal value in numerous places, which is bad, we empower ourselves to reference a static field in numerous places, which is almost exactly as bad. Perhaps instead we should consider what concept that value represents that needs to be reused all over our code and find a way to encapsulate that responsibility.



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.