The Code Whisperer

Practical, on the ground advice for efficient software development

Archive for the ‘Techniques’


The Importance of Finishing

Over the summer one topic has come to light several times - the importance of finishing what you started. It’s very easy to get distracted on medium and long term projects and get pulled into the exciting start of another, or just get fed up with the current project. You can see this in work and hobbies, the classified section of car restoration magazines has a number of unfinished projects for sale.

Planning is a vital weapon to fight this attrition. Planning achieves a number of things aside from knowing when you are going to finish:

  • By walking through the project a number of times you are more likely to spot where problems can occur than if you carry on without planning
  • You have considerable more confidence in what you are doing as you have been through it several times on paper and in your head
  • Provided you re-plan, a diversion to a different project, whilst disruptive, means you know when you are going to finish the original project and what is required to complete it

I recently carried out some consultancy for a software development company that had 3 bug tracking systems and 2 source control systems on of which had numerous databases scattered over the network. Project documents were held on a Sharepoint server, one of the bug tracking systems and in several of one of the source control system’s databases. For the source control system there was an upgrade in place and to be fair there will always be 2 source control systems so that the previous versions of code are kept, but no plan to migrate from one to the other, so you end up in limbo where the vast majority of a project has been migrated, but not all of it.

In this case there was insufficient planning involved in the move. Problems were identified but not acted upon, leaving it until the physical migration to establish the best way, but which time a fix had been put in that meant some files were not under the new source control system. It works, but only when the developers know the tricks. When staff turnover is high this sort of information and the reasons behind it get lost and a temporary fix becomes permanent because “that’s the way we’ve always done it”.

Part of the reason my kayak trip along The Thames took so long to prepare for was done to constantly walking through and revising the plan that covered leading up to the day and the day itself. The result was that the day ran smoothly with eveyone knewing what they were supposed to do and when.

Finishing a task and striking from the list always feels good, there’s no nagging about it in the back of your mind, which frees up thinking power for the next task. If you do have to divert, make sure you continually update the plan to reflect the time taken on the diversion and put down enough information so it can be picked up again. Don’t assume you’ll remember the little details, often the time lag is longer than you expect.

36 Common Software Development Mistakes
20. Insufficient Management Controls

For project development knowing where you are in (in terms of the plan) and when you are going to finish are the two key indicators and also the two questions the project manager will be asked the most.

In order to answer the second question you have to be able to answer the first, and that’s where the problems start.

The project plan must track the time take on a task as well as the actual progress. Having spent 5 hours on a 10 hour task implies it’s 50% complete, but is it? Assumption can be a bad thing, and assuming the allocated time is always going to be correct is a mistake. Personally I like to have tasks broken down so each one is scheduled to take a day or less, two days at the most. By scheduling  this way, the impact of inaccuracies with collecting actual progress are minimised.

In order to say where you are with a task it’s important to define complete. This is much easier earlier on when producing specifications and coding, but when the various stages of testing are under way this becomes harder. Note that whilst defining “done”, knowing how far away from “done” a developer is harder to determine, hence the one day scheduled tasks. Depending on the application you may have a zero defect target before releasing the software, or it may be no severity 1 or 2 defects and a maximum of 20 severity 3. Defining this early on means that the customer (whether it’s an external customer or an internal department) knows what will be delivered.

Once testing outside the development team commences, a defect tracking tool is essential. We’ll cover this topic in more detail in a few posts time, but metrics from this tool, particularly the active defect count will give a useful insight into the status of testing. The active defect count tends to rise very quickly when testing starts and then tail off slowly. Another useful metric is the number of new defects raised. Again this will initially be quite high, but as the quality of the application improves this metric will reduce.

Formula 1 teams capture a massive amount of data from their cars to establish how they are running and the effect of changes. There is a saying “if you can’t measure it you can’t improve it”, which I don’t entirely agree with as it should be “if you can’t measure it you can’t measure the effect of change” that applies here. Software development should have a number of metrics that are constantly being collected, as automatically as possible, for the same reasons as the Formula 1 team. The metrics may indicate changes required to the schedule or more attention is required in these areas. The effect is the same, total control of the project.

36 Common Software Development Mistakes
19. Inadequate Testing

Let me say straight away that, outside of unit and system testing, I’m not an experienced tester. I believe you have to have a certain mindset to be really good at it and, although this may seem harsh, a passion for breaking things rather than building things, albeit all for the greater good. I met a number of exceptionally good testers in the past and they all share similar approaches, plus a slightly mistrusting look in their eyes.

The amount and quality of testing developers will carry out varies greatly. Putting aside any lack of enthusiasm for breaking their own code, other factors such as the architecture of the system, the quality of the test plan, if produced, and whether automated tools can be applied will influence the number of bugs remaining after system testing.

Many years ago I went to a short seminar about testing. It sounds boring but the managing director of the company leading the seminar was so enthusiastic about testing I came out enthused. He spoke in depth about a concept called the engineering V, where you have business requirements at the top of the V and development almost at the bottom. The design and development part of the project runs along the left side of the V, top to bottom and the testing part on the right hand side from the bottom to the top of the V. The idea was that you tested against the opposing specification, so unit and system testing would be against the technical design, user acceptance test against the business requirements and so on. The odd thing is that this concept is so clear in my mind over 15 years later but I can find no reference to it anywhere.

This concept does rely on top quality requirements and design documents being produced and test plans directly from these documents.

Personally I like the idea of being able to automatically test applications, so that the same tests can be easily applied against each build and release. Sometimes this consists of bespoke test harnesses testing software components, sometimes automated test tools attacking the entire application. I also favour having test plans for unit and system testing written as part of the technical design, with an indication of the plan’s successful completion forming part of the code
review.

Above all I value a user acceptance testing team that lives and breathes testing, but it’s important not to allow an “us and them” environment to exist between the development and test teams. I did hear a story about one company that attempted to improve the quality of its software by paying the test team a bonus for each bug found and the development team a bonus for each bug fixed. Needless to say the number of bugs found by the test team and fixed shot up dramatically helped by an “agreement” between the two departments, and the scheme was quickly dropped.

A Warning About Multiple Code Streams

Source control systems such as Rational’s ClearCase and the open source products CVS and Subversion, make it relatively easy to branch an application’s source code to produce, say, different versions for different customers or maybe work is taking place that can be carried out by two developers independently. Merging the branch back into the main code stream can be achieved using a variety of tools, for example TortoiseSVN, for Subversion, or the brilliant Beyond Compare, which compares files and directories rather than working on the source control system directly.

Notice the last sentence doesn’t include the word “easily”. That’s because it isn’t, particularly when both streams have had changes applied and/or someone other than the original developer is carrying out the merge.

The pain of merging can be eased by applying a few simple rules.

  • Make sure your coding standards have a comment block defined that goes at the start and end of every change. The comment block should show the developer, date of change, reference to the bug or business requirement/technical design associated with the change and a concise but informative description of the change
  • Coding standards should also advise on whether unwanted code is commented out or removed. Whichever technique is adopted it should be consistently applied and the same comment block header and footer format used as if making changes to the code
  • When checking code back into the source control system a sensible and detailed description of the change, including reference to the bug or business requirement/technical design associated with the change must be entered. It’s not acceptable to put nothing or a banal statement such as “Changed made”
  • Code reviews must be carried out and should include a check of the source control descriptions and possibly also review the changes made between the two version in source control to verify that each change has the correct comment blocks
  • When complete build the application and test it. Don’t leave this until the next formal build as any knowledge gained during the merge may be forgotten

36 Common Software Development Mistakes
18. Inadequate Requirements

If you look at the collection and documentation of requirements for a software application as the foundations of a building, it’s easy to see why any weakness here has a major effect in the delivered item, whether functionality that can’t be implemented fully or delayed time to deliver.

Requirements gathering and documentation fail for many reasons, and each company and application will be different, however simply put you need to have business analysts doing this work that understand the business and know how to document business requirements and processes to people who don’t. It’s imperative that the business analysts write in a clear manner, clarifying complicated areas. In my view it’s better for the business analyst to spend more time producing a more understandable document than the developer thinking her or she understands it but wasting time developing in the wrong direction.

In all documents, not just business requirements and processes, I like to apply Rudyard Kipling’s epigraph from his short story The Elephant’s Child, which has become known as Kipling’s Six Honest Serving Men.

I keep six honest serving-men
(They taught me all I knew);
Their names are What and Why and When
And How and Where and Who.

This on its own isn’t going to produce fantastic specifications, but I find it useful particularly when I know the subject matter well and need to provide documentation to people that don’t, whether it’s business requirements, technical design, user manual or operations manual.

Use of peer reviews on business requirements will improve their quality particularly if it includes reviewers that aren’t familiar with that part of the business or industry.

In my experience a significant amount of the difficulties caused by business requirements (and technical design) is that the author assumes that the reader has a higher level of understanding than they actually do. In a small company with a low turnover of staff you can get away with this, but in any other case it’s a recipe for disaster. If you are outsourcing work then business requirements and, particularly, technical designs must be of the highest quality to prevent a large number of test/correct cycles.

One last point is to do with testing, in particular user acceptance testing (UAT). I would expect UAT to concentrate on testing the application against the business requirements. In a sensible development the customer would have sight of the business requirements documentation and signed them off, or provided their own “list”. Issues found in the testing should reference the business requirements and some form of reference number. If that reference number hasn’t been followed through into the technical design and actual coding, then the ability to quickly identify the location of the problem, based on the business requirement, is lost. In additional any ability to measure the time and/or cost of developing different parts of the business requirements are just about impossible. I highly recommend that some form of reference to the business requirements is carried through technical design, coding and testing.

36 Common Software Development Mistakes
17. Wasted Time During Fuzzy Front End

The front end in this context is not the GUI but the period between the project’s conception and the point it actually starts. This period, which can last from days to years, can include activities such as feasibility studies, budgeting and gaining sponsors. These are all important tasks, but can take too long, resulting in a shortened development plan.

It’s obviously better to reduce time in the front end processes and spend it during development, but really this needs to identified as early as possible. Look at the tasks being carried out and plan them, taking into account events such as financial year ends, stakeholder’s holidays and make sure these don’t coincide with decisions that require these people. Also try to carry out the task that is most likely to halt the project as early as possible so that the minimum of time and effort is wasted. If possible identify bottlenecks in the process, for example sign off by senior management, and try to bring those forward in the process, and also smooth the way for the activity.

It’s not only large projects that suffer from this problem. I’ve had many small web projects that I’ve invested a fair bit of time researching and scoping only for the client to go very quiet, then suddenly phoning up some time later, all fired up and wanting it done immediately. This is fine if you have the capacity to do it, but more often than not this isn’t the case, which is a difficult message to relay to the enthusiastic client.

36 Common Software Development Mistakes
16. Planning Failures

There are books and books about planning projects, and I’m not going to attempt to replace them in one short posting!

I have a few observations over the years I would like to share.

Planning not taken seriously. For a plan to be of any use it has to be thought out, realistic, published and have tracking of time spent and progress of the task. In my opinion task need to be split down to a daily level for the plan to be worthwhile, otherwise it’s harder to know if the progress is behind the plan. If any of these don’t apply, and normally it’s most of them not just one, the planning process isn’t being taken seriously enough for it to be a worthwhile exercise.

Tasks missing. It’s easy to omit tasks from a plan and often they are common run of the mill activities that would take place as a matter of course. However omitting them from the plan has an effect - it’s time spent not allocated, which could cause the project to slip. I look at a plan as any other project document and have it peer reviewed and/or reviewed by the project team. If tasks are identified later in the project it’s crucial to add them in for three reasons. 1, you are more likely to remember them next time; 2, it allows you to adjust the plan and, if required, delivery dates; and 3, there’s an indication the task has been carried out.

Not revising estimates. Often estimates are carried out by the wrong people - sales staff, senior managers or customers. Estimates produced by developers sometimes are under the actual time required. We all know this, but revising estimates and the plan is very rare. Why?

Abandoning the plan. I’ve seen this time and time again. A project is late or chaotic, so any attempts to maintain the plan or any measured progress of the project are abandoned. The project then goes out of control, with any delivery dates a stab in the dark. It is possible to regain control of a project in this state, but take a special project manager. I have met a project manager that recovered what appeared to be a hopeless project. Possibly the most irritating chap I’ve met, but at the same time was interested in one thing - delivery of the project in the shortest possible time. He wasn’t afraid to tell the customer it would be a week late, and he delivered it when he said it would be delivered. Pure genius.

I’m sure there are more. If you have any observations on planning failure, I would like to hear them, so drop me a line at nigel(at)code-whisperer.com.

36 Common Software Development Mistakes
14. Insufficient Risk Management

This topic pulls together several other of the 36 common mistakes, for example feature creep and the use of leading edge technology. Many books have been written on risk management and I’m not going to attempt to distill them down to one blog posting, instead some definitions and key points.

A risk is an undesired event that has a cause and a consequence. Risk management is the systematic process of identifying risk, analysing and either responding to it or planning to minimise or avoid it.

I heard of some astonishing, but quite logical, risk management at a meeting at IBM many years ago. They had a project on a client’s site that involved the teams driving a fair distance each week for a number of months. The project manager calculated the number of miles that would be driven and then looked up the average number of miles between serious road accidents. Statistically for the number of miles to be driven there would be one serious road accident. Fortunately all journeys were completed without incident, but there was a fallback process in place had there been. Whilst this may appear cold hearted, it doesn’t exclude caring for the team members involved in the accident, in fact quite the reverse. Just as we rely on the police, ambulance and fire services in a road accident, who have plan and train constantly for this sort of activity, so IBM was creating a process that would allow the project to carry on whilst caring for the team members. If an accident had have happened unplanned for, the project manager would have had to work out what to do on the spot and implement it. By having a plan someone else can put into practise, the project manager is free to concern himself with the well being of his team members.

There’s as many ways of handling risk management as cooking eggs, so I’m just going to touch on the general steps.

Risk identification - prepare a list as part of project planning, but also identify risks during the project.

Qualiative risk analysis - this is a prioritised list of risks, ranked by the cost of correcting the risk, which could be expressed in time or money.

Quantitative risk analysis - this is the likelihood of the project not achieving its objectives if the risk occurs or the probability that the risk will occur. The expected cost can be calculated by multiplying the expected cost from the qualitative analysis with the probability of the risk occurring.

Risk response planning - look at the ways the risk can be minimised or how it will be handled and cost, using the same units as before (i.e. time or money). Minimisation of risk can consist of work you will need to do to minimise the risk and work you will need to do if the risk occurs. The cost of dealing with the risk (if it occurs) and the cost of minimising the risk can be compared and a decision made on more scientific grounds. For example, if a project was using a new database technology, you can calculate the cost of changing the database technology late in the project if a problem was found in the new technology and compare it against isolating the new technology as part of the design and having to change a smaller amount if a problem arises.

Risk monitoring and control - as the project progresses the possibility of a risk occurring may rise or fall and other risks may be identified. Just as the project plan is adjusted as it progresses, the risk management steps here should also be constantly revised and adjusted.

36 Common Software Development Mistakes
10. Lack of User Input

Before we dive into this one, lets just remind ourselves why software exists.

To solve a “problem” or gain an advantage for the person that uses the software

And that’s it. You could argue that low level software such as drivers fall outside of this, but indirectly they solve a problem, whether it’s a USB driver for a MP3 player (advantage: listen to music whilst walking) or a printer driver (advantage: print photographs at home).

You have to involve people who will use the software in as many stages of the development as possible. This can turn out to be painful and there is a danger of bending the software to meet one person’s opinion so needs to be approached with common sense and sufficient users to form a genuine consensus. Don’t forget, however, you won’t please all of the people all of the time, so beware spend large amounts of time adding a small amount of functionality that a few people will use infrequently (unless they are prepared to pay!).

This sort of activity at the requirements gathering stage is fine, the design is fluid and if you’ve produced a prototype or wire frame then the feedback will be based on what the users see rather than what they imagine. However the later in the project this feedback is gathered the more time and money it will take to change, but rather than dismiss it out of hand, look at whether there would be a suitable return on the investment.

A couple of pointers about gathering feedback. If you have a demonstrable application, consider using a video camera or for web based software a service such as CrazyEgg to record how the user interacts with the screen. In Predictably Irrational: The Hidden Forces That Shape Our Decisions, Dan Ariely carries out controlled tests that indicate how we make decisions based on certain environmental conditions. One test he has people select a free sample of beer from a list of four different beers, some with exciting descriptions, some with dull. When people publicly make their choice, they are more likely to choose a beer that hasn’t been selected by someone else at the table that choose the one that sounds the best or the same beer is chosen by each person at the table (this may be a cultural difference). However when the selection is made privately more people chose the better described beer.

I’m not suggesting that you ply users with free beer, but I am suggesting that you collect information privately possibly using a feedback form. The feedback shouldn’t be anonymous as you may need further clarification, but by removing any social convention by making comments publicly you will get better quality feedback.

To highlight the need for user input, a few years ago I wrote an application called Restoration Manager that helps locate parts from a vehicle that’s being restored over time. Having spent many hours searching for parts I had removed from a car weeks earlier, thinking I would be putting it back on in a couple of days, I felt I was in just the right position to design the software. A mate of mine who is an engineer and spends his days restoring cars and bikes and who doesn’t use a computer a great deal offered to test an early version, which was a good job as I was wide of the mark in some places. Interestingly I recruited 10 testers for a later release with the offer of free software and despite their initial interest only 3 actually downloaded the software and only 1 actually fed anything back, which was to do with the installation routine.

Deployment Woes

I’m unable to continue the classic mistakes series again today due to a problem one of my private clients is having with a software deployment. To help them hit their delivery date I’m rolling my sleeves up and attacking the problem, as Marku Alen, one of my rallying heroes from the 1980s’ would say “Maximum attack ! 110 percent!”

Typically some, if not all, of the problems could have been avoided.

  • A merge from 2 code streams into another code stream had taken place just prior to the building of the software. There was no time for testing, not even the stored procedures have been compiled. The script to compile stored procedures into the database is failing in numerous places
  • The deployment is split into two tasks, handled by two different departments. The department that handles the creation of the install kit using Installshield has one person that knows how to do this, and he’s on holiday
  • The comprehensive operations manual hasn’t been updated for over 12 months, despite changes to the file server locations and an upgrade to Installshield 12
  • An error produced in Installshield allows the MSI to be produced, but locks the files Installshield produces preventing another MSI to be generated in that directory. So every time the MSI is produced another directory has to be created and the necessary files copied over. This may have been overcome, but hasn’t been documented by the chap that normally handles it

How this could be avoided:

  • Merging is a horrid task, very boring and easy to get wrong. In this case what should have happened is a merge from one code stream into another, fully test, or at least a smoke test, merge in the second code stream and fully retest. In adds 2 to 3 days to the merge, but it provides confidence in the application that currently isn’t there. Bearing in mind that this is almost a release candidate, releasing unstable code at this stage is foolhardy
  • As a general rule never check code into shared source control system when that code doesn’t compile. There are downsides to this approach, for example amended code only existing on the developer’s computer for a period of time, but this risk can be minimised with a comprehensive backup plan. When you have more than one developer working on a code stream, I believe checking in only code that will compile is vital to prevent developers wasting their time getting someone else’s code to compile. The same applies to stored procedures
  • Keep operations manuals up to date. The idea is that just about anyone in the development team could pick up the manual and produce, in this case, application binaries and the setup kit. Additional information, such as problems with Installshield can also be added to a departmental or company wiki