Wednesday, November 20, 2013

Order of programming tasks

Yesterday I had an interesting debate with my colleague while we were pair programming. We were implementing a client for REST API and argued whether we should first implement the happy case or failure scenarios. I voted for the former, he was for the latter.

My colleague was worried that if we don't start with the failure scenarios, there will be a temptation for not doing them at all. I replied that sure it requires discipline from us that we won't stop after the happy case and rush to some other programming tasks. Nevertheless, I saw more value in starting with the happy scenario because that way we could help a third developer who was implementing the orchestration part of the feature and was dependent on our code.

Later I started to think more about this conversation because I felt I couldn't argue my opinions well enough, although we decided to start as I suggested. I then realised that my argument was based on small batch and options thinking. Let's put it this way. If we had started with the failure scenarios, we wouldn't have had anything to share for the third developer before we finish both the failure and happy scenarios. I would call that as a big batch approach. On the other hand, when we did vice versa, it created the team an option to use the finished code and utilise it in the other parts of the system - while knowing that it is not the perfect code yet. This was a small batch approach.

Another kind of theoretical way to think it is from agile software development point of view. In agile software development you should be doing the most important thing next. What is most important depends on what brings most value. In our case the happy case created more value than the failure scenarios.

I still agree with my colleague that there can be a temptation to stop with the happy case and kind of forget doing the boring failure handling. But like I said above, it requires discipline, which is one attribute that can be attached to experienced programmers - who I think we are. One way to be disciplined is to write failure case tasks for the user story, another is to have a proper definition of done for stories in general. But all in all, we shouldn't give up from value just because we are afraid of not being professional enough developers.


  1. I agree with doing the most valuable test case first.

    However, in my opinion the problem of not completing the test cases is usually not "lack of discipline" but forgetfulness.

    If you are using a good testing tool (I would say "a proper testing tool"), you can write stubs for all the failure cases and mark them as "Pending" or similar.

    This way, you are left with a reminder to do the failure test cases later on when you have provided the most valuable batch first.

    1. The pending test tip is a good addition. I have used it personally for example with RSpec tests (or specs).

      But anyway, I think that if you recognise important things to be coded but forget to code them because you didn't write them down, it's lack of discipline.

    2. My point of view on this is almost exactly that of your first Anons': Thanks to the myriad ways my work gets interrupted all the time, I really need to write down the more obscure but still relevant edge cases that need to be tested.

      You can call it a lack of discipline, but when you get thrown into a meeting for the rest of the day and return on the next morning - having committed the happy case and obvious failure cases, you truly might not remember the rest - and that's where @Ignore:d reminder test cases help.

    3. I was probably a bit unclear what I meant. I think that writing the edge cases down, either as tasks or pending test cases, is exactly a disciplined way of working. Not doing that can be called as "forgetting" or lack of discipline.

  2. I guess it depends if 'failure scenarios' are business logic or just exception cases? I'd write test cases for the REST api first based on real examples.

    1. I don't think it matters. The reasoning is same in both cases - unless you really want to first implement e.g. "login failed" instead of "login successful". I would probably start with the latter in which case both business logic and (e.g.) IO exceptions go to the same category: they provide less value than the happy case scenario.