One of the common answers a developer gives when s/he notices a bug is that “it works in my machine”. This was so common and always boils down to the configuration difference between the testing environments and development environments. It is not so easy to keep the development and testing environments very similar but lots of those could be scripted and made automated such that it is an executable document. There are also lots of development hygiene practices that needs to be strictly adhered to avoid these kind of bugs.
Where could things go wrong?
There are many things that could go wrong, here are some of them in no particular order.
- Poor version control – Either the code is not checked in(sometimes extra files locally modified for debugging) or the branching/merging is mismanaged.
- Incorrect dependencies and libraries – The dependencies/libraries are manually copied to the servers. Example – copying some jar files to tomcat, could easily go out of version between different machines.
- Testing only in debugging mode – When testing at the developer’s machine, developers have a tendency to run in debug, breakpoints in the code will give ample time for the application so that synchronous issues do not crop up during developer’s testing.
- Not testing at all – This sounds silly, but when the pressure is high chances are that the code is committed without tests and then bugs have to appear to give time to finish the coding.
- Incorrect environments and test data – Large projects have a tough time managing test data and environments, developers could be pointing to an outdated external environment or using only a narrow set of test data.
“Image courtesy of Grant Cochrane / FreeDigitalPhotos.net”.
Are we going in circles? We first had a single large computer, then we had multiple terminals connected to it and used it. Later personal computers helped breakaway from large ones and dumb terminals. We were able to work in our computers all day without internet, now computers without internet is like fish without water. People worked in large open floors then cubicles gained popularity and again open plan offices were used; now people are debating whether open plan offices are beneficial or not.
Why do we vacillate? If you have heard or read the “The retrospective prime directive“, the answer lies there. We are dealing with increasingly large systems with a cause and effect so interlinked and having delayed feedback that we will only be able to realize in hindsight. As times change so do the environment and the abilities, so what worked well few years back is questionable for a current situation. So the best is to keep looking for the right fit for the given condition and it is not vacillation, it is just we are getting tuned to current state of the system.
The adjustment to the current state looks like we keep vacillating between the choices, but we are not vacillating. We are just adapting.
Image courtesy of cooldesign / FreeDigitalPhotos.net
I get a chance to meet lots of people who have a good exposure to the manufacturing industry either by work or education. If we take a look at the Cynefin framework, manufacturing industry fits in the ‘complicated’ quadrant. In this context if we are to create a wrist watch then there will be a clear design on how to create the parts and standard instructions on how to safely assemble the watch. This works in most of the cases and people will gain dexterity over time and will be able to assemble watches at a much faster pace. What is necessary here are the design and the standard instructions to assemble; incase someone else finds a better way then the standard instruction is updated with the new method.
Software work on the other hand is knowledge based and fits in the ‘Complex’ quadrant. There are some good practices for basic things like clean code, continuous integration etc but there is no defined way to approach it using the methods which apply to tasks in the ‘Complicated’ quadrant. If I am assembling a watch or a similar task, it is possible for me to split my work into 1 hour increments and produce output at a predictable pace. I can also stop doing the work in between, attend a meeting and resume work later on without much impact to productivity after resuming work.
Knowledge workers such as software developers cannot do this, their time increments are more like 3~4 hours. A break in the flow of work is bound to cause rework from scratch. Concentration of task at hand is of prime importance and if plans are made such a way that there is a meeting scheduled in between the 3~4 hour stretch of window, it will impact the productivity for sure. Also the power of context is too pronounced, the productivity will be much lower earlier in the development cycle and will progress much faster as common understanding of the system emerges. Plans usually consider only linear throughput and that adds pressure on the team to be at peak from the initial phases of the project.
What should we consider if we are dealing with knowledge work especially if we have been exposed to manufacturing or similar sector which fits the ‘Complicated’ quadrant in Cynefin framework?
- Plan for a progressive increase in throughput
- Standard instructions and processes will not fit and may prove to be counter productive
- Work requires thinking time, concentration at task comes with unbroken attention, plan for developer time in chunks of 4 hours
- Reflection is as necessary hands on coding. Tasks like staring outside of the window, enjoying the coffee or doing nothing with eyes closed are not unproductive, it helps reflections which helps innvoation
- A degree of autonomy is required, it is better to let the team evolve the design based on their experience than forcing an expert’s opinion on the team
- There has to be avenues for continuous learning and sharing the learnings
Image courtesy of stock images / FreeDigitalPhotos.net