Many of the indian cities today were part of planned development and expansion several decades ago. Plenty of  self sufficient segments of land which could be administered very well by local civic body comprised of cities. These segments had a water tank/lake, playgrounds, schools, libraries/community centers, health care centers, bus depots and segregation of commercial and residential areas. Then there comes a boom in economy and the demand for revenue generating buildings rise. Land becomes a premium and suburbs begin to become part of an extension of the city.

What was once considered to be essential like schools, libraries and other backbones takes a backseat. The focus is on converting as much land as possible into dwelling units and business centers. The demand of of schools, health care centers, libraries, playgrounds are all proportional to the population. As the growth of the suburb is not organic, the essential backbones get built much farther away than in the desired localities. People spend a great deal of time together with their families during transit to work, school and clinics. Simple tasks which was once very easy to accomplish because someone lived in the city becomes a tough task which keeps them occupied for a good part of their productive weekday. Reduced physical connection, long commute times, erratic food habits, irregular sleep patterns comes as freebies because of an unplanned rapid development.

I have observed large software projects which start small with a plan in mind. Backbones like continuous integration, testing frameworks, common goals for the team gets set and progress starts. The ramp up of the team is done slowly and organically such a way that the new members gets a good idea about the goals of the team and the individuals. The code begins to grow and a conscious effort is needed to monitor to modularize or improve its design to increase efficiency. At some point if the business decides to increase the spending on IT to add more functionality in a short period of time, the immediate tangible number which comes to mind is the number of people and the amount of work done. It is even more easy to use those numbers and set up a metric in place to monitor progress, create plans based on extrapolations/number crunches and execute them as necessary.

Sadly the metrics driven development is like building skyscrapers by counting just the floors built without a second thought about the long term habitability of it. An illusion of progress is created as more functionality is added in a short time by the sudden increase in team size, which makes the other not so visible aspects of a software project like design, code quality, usability to become invisible. More effort gets centered on the deadline with added functionality and individuals become more focussed on the task at hand ignoring the other aspects. Gradually the mindset shifts from building a castle to laying the bricks in order.  It is necessary to acknowledge that an organic ramp up is necessary and limit the team size to a level where plain interactions and code base are enough for communication. If there is a need to increase the team size to get more work done, after a careful analysis work should be split, parallelized and a new team has to be forked off.

Image: Damian Brandon / FreeDigitalPhotos.net

Most of the projects we start from scratch; we usually start with a build time of less than 2 minutes with all the unit tests, code analysis metrics and reports. If you have heard about the parable of the boiling frog, then something similar happens over the course of few months when the code has gradually grown in a large size and increasing the build time with it. My observation in one of the teams few years ago was that we got used to build taking longer and which was considered more of a break from an hour or two of coding. What we did not realize was that subconsciously we were aware that the build is taking longer and hence we accumulated a large piece of code before checking instead of smaller chunks. This had an observable problem that there were build breaks just before we were heading home and developers sometimes take good amount of time merging code before checking in.

XKCD compile time

It was not until we reached a tipping point that the entire team realized that the build time has risen to a point where it hampers a smooth churn of development. To our surprise it was only few hours effort to get the build to under 4 minutes from 12-14 minutes. From there on some of us keep a conscious watch on the build times and have a 5 minute unwritten blanket rule to jump on fixing it before it grows too large. Usually the problem was a monolithic code base which keeps the build time too high. Some frameworks like GWT will compile JavaScript for all browsers which might not be required to be done for every build. Making use of the multiple cores now available so widely is also an option to consider. Ramdisk is also another option.

The lesser the build time, the more it encourages us to check in code often which reduces merge conflicts; eventually leading to a mature continuous integration. A mature continuous integration ensure reliable and effective delivery.

Every time I find it difficult to think of a good test to start, I am always tempted to try backdoors like getters, setters to help get started. The backdoors are not limited to getters and setters alone. Here is a list of my observations which has been used only for writing unit tests in Java easier.

  • Getters/Setters
  • Constructors
  • Equals implementation
  • Protected or package private access specifiers for variables and methods
  • ToString implementation
  • Special backdoor methods to alter the state of an object (The worst of all)

Any line of code which exists other than for another production code, it encourages a programmer in the future to exploit that backdoor for quick gains. As the tests are the specification to the production software, it is better to resist the tempation to use any of these. It also causes increase in code length and also an excuse for more people to follow the same path. The more time and effort I had spent trying to avoid backdoors, I have benefitted with more clarity in design. The benefits have prompted me to have routine static checks in the code base to keep them at check.

A question and a counter argument posed by a peer who belonged to another school of thought. If tests are considered to be first class consumers of production code, then is it right to have some backdoors help ease writing tests faster? Comments?