Increasing your software teams efficiency and code quality -

Increasing your software teams efficiency and code quality


As we move to the next generation technologies, software production is becoming a much larger part of the embedded product development process. Critical areas like brake systems of automobile industry, gas control systems and in-home appliances use software technology with quality becoming a key factor.

Things like time to market, defective processes and resource constraints leads to such defective unstable systems. But end users and customers prefer products with stability and quality rather than feature-rich, but unstable, systems.

When we say defective product, it's not the product but the method used in creating the product that is defective. Sometimes lesser energy within the system could also lead to such unstable systems. Now let us look into seven basic areas of a software development process that need increased attention to improve quality of the system.

#1 – Document close to the source
Software developers presume documentation is not part of their pie. As a result, the assumptions made during coding do not get captured properly. Knowledge does not transfer properly and this often leads to catastrophic effects.

For example, while programming, a developer accesses a structure member by indexing or assumes that the byte in the nth offset is of interest to him. In the process of the maintenance lifecycle when a new engineer adds a member to the structure or reorganizes the structure, the code will become messy.

If no proper explanation is attached to the piece of code that assumes indexing, data recovery from the defect will be tricky. Such assumptions might not also get properly captured in the design.

It's better to document closely to the assumption made in the code. Tools such as doxygen help us generate design documents from the source code. Documenting close to the source will reduce the risk of assumptions and also reduces the time required to create separate design documents.

Asserts are also a kind of documentation that should be added to validate the assumptions. Lesser assumptions during development lead to more stable quality systems.

#2 – Version-control system
One of the important stages in any project life cycle is version control. Normally a version-control system is viewed as a place to store project documents. A version-control system is a company's knowledge base.

Version control can be a valuable source of knowledge for future engineers or when we dig back into a project after a few years. Let's consider a scenario involving a of change in the source file. Engineers generally update the version-control systems as below:

------------------snip------------------From:-----snip-----free(ptr);-----snip-----To:-----snip-----if(ptr != NULL){    free(ptr);}-----snip-----Log Message:Check pointer before freeing.------------------snip------------------   

As we look into the change log after years or a new engineer looks into the change log, there would be no clue why the code was changed. The process has to be adapted to ensure that the change log conveys the change reason properly.

In a summary, the log has to convey the what, why, and how of the change made. “What” could refer to the bug ID, “why” could refer to the root cause, and “how” refers to how the problem was solved. Such efforts minimize the assumptions made after years when the same piece of code requires some refactoring. Minimizing assumptions helps to increase quality of the systems.

#3 – QA, QC, & individual developer
Next is the testing process, which is referred to as quality assurance (QA). But testing is really quality control or QC. It's a control mechanism that comes after an item has been built.

Testing (QA and QC) can never assure that the item will meet its quality requirement. What gives assurance of quality is the development process. QC (or testing) is necessary to verify and correct the process.

Developers should, during development, adopt practices that will give assurance of quality.

QA is the responsibility of each developer. Often developers have dismissive attitudes toward testing. These attitudes need to be changed. Developers have to adopt unit-testing methods and test the code for path coverage.

The process should also ensure that code is developed in such a way that it's testable. Developers need to document on the function headers the assumptions made by the functions and scenarios that would cover the function or the control path.

When the customer finds defects, it means there is some problem in the process. This indicates testing metho should be improved.

Suppose a defect has been identified by a customer and reveals a gap in the testing method. New processes to improve testing have to be brought in. Preparing test matrices for each feature would help increase test coverage and thereby minimize the chance of defects escaping the test scenarios that were not considered earlier.

#4 – Releases method
Quality issues most often result because of stagnancy in the process. This is true in any industry, but especially so in the software industry, where people remember slipped dates, not slipped features.

To keep momentum going in the team's production of software, regular releases should be planned. Regular releases allow us to deliver product on time. Regular releases also means control over the product, an important consideration. A regular release allows us to review, practice, and refine processes and practices.

Regular incremental releases means adding smallìfeaturettes to the system and keeping up the energy within the system. It also allows us to exercise the software with more testing and makes the system less prone to defects.

An embedded system should include the following elements: a must part of the specification, followed by the shoulds and then by the maybes . It should also allow the must part to be tested thrice.

#5 – Cause analysis
Defects should be considered an unavoidable part of any developing system. When a defect is reported, the general practice is to do defect analysis, which is really defect location. As soon as the defect has been rectified, the defect is considered closed. This is the common practice normally followed in most software-development methods.

When defects are caught, especially those caught in regression testing and by the customer–especially the latter–this is indicative of problems in the process. Methods need to be adapted to reduce such occurrence. To achieve this we particularly need to improve the defect-analysis process.

Methods like the “5 Whys” popularized in Kaizen The Key to Japan's Competitive Success by Masaaki Imai need to be brought in to find the real cause as to why the defect was introduced and why the team failed to detect it before it reached the customer.

Such processes will help us not just fix the defects but also allow us to find the root cause and solve similar defects that could crop up because of the root cause.

#6 – Capturing metrics
Learning from mistakes is the key to success. Getting feedback from the previous releases is essential. The lessons learnt have to be reduced to check points on a checklist.

Checklists are to be used by developers and reviewers. This is to ensure that correct practices are adopted. The lessons learnt have to be applied horizontally to similar modules and products.

Some of the most important metrics for an embedded product are is testing for code coverage and defect statistics. Tests for code coverage should include not just code coverage but also path coverage. Defect statistics will enable us to identify the areas where test coverage has to improve. Such procedures allow us to reduce the defects that slip in to the hands of the customer.

#7 – Behavioral changes
Among all the processes, making behavioral changes is the most important–and the most tedious to implement. Changing a process, which people are accustomed to, means playing on people's emotions. This will be an uphill task. While implementing changes, the motto could be “practice and adopt” the suggested focus areas.

Training that includes both new joiners and old timers would bring about the behavioral changes required to achieve the much needed improvement. And on-the-job training focused on quality practices serves better than training using presentations. Training needs to gauge the trainees on how much knowledge has gone into the mind of the trainees.

Let's consider a lab exercise sample after a session of coding practices and software construction principles.

LinkerError1.c#include "LinkerError.h"void SomeFunction_1(){   int siVar1;   siVar1 = siAvoidGlobalVariable ;}LinkerError2.c#include "LinkerError.h"void SomeFunction_2(){   int siVar1 = 0;   siAvoidGlobalVariable = siVar1 ;}void main(){}LinkerError.h/*    Some Global Variable*/int siAvoidGlobalVariable = 0;   

The above lab training exercise is a sample used to gauge the trainee's knowledge after training on coding practices and software-construction principles. The exercise is to find and resolve a linker error.

Normally trainees solve it by adding extern. But this doesn't reflect the necessary behavioral change. Instead, it's necessary for the trainee to proactively remove global variables and provide interface functions that would indicate the behavioral change necessary for quality product.

Exercises can also be derived from the defective coding practices that caused serious quality problems and help trainees understand how not to program.

A journey to quality
The procedures described here have all been successfully adopted and practiced and have resulted in processes that made quality improvements happen. But vision and commitment are needed to sail through turbulent tides that may result and reach shores of high quality and customer satisfaction at the end of the process.

Regupathy Rajaram is a senior software engineer working in Singapore software industry. He has a decade of experience in the embedded system domain including compiler and tools development for embedded systems. You may reach him at .

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.