Published date: 21 November 2018 You may wonder why humans can undertake large and complex construction projects successfully, and yet IT companies struggle to deliver software projects without bugs. This page discusses some reasons why errors happen in software development and suggestions on what can be done to reduce or avoid these errors. Two types of errors Roughly speaking, ‘programming errors’ can be divided into two categories: The first one consists of actual errors in which something is not working; while the second one is more of an ‘understanding error’ in which the client has expected a different result than what he or she received. We discuss possible reasons for both of these categories. These reasons are not meant to tolerate shoddy software development practices—rather, we're saying that even with an excellent process in place, software development remains a highly challenging field. Why do programming errors occur? A programming error is an error that causes a website, webshop, app, or any other software to suddenly not work or behave strangely in different situations. This usually happens because of a bug in the code, or because an external system is not working as expected. Programming errors can be very frustrating because they often occur at the most inconvenient times, and in unexpected corners of your system. Typically, errors occur because the programmer: May have failed to foresee a specific user action or behavior; Made a definite error; Forgot to check if the data required to complete an action is missing or incorrect; Utilized an external system that is offline or delivers incorrect data; Utilized ‘libraries’, i.e., program types built into the operating system, such as Windows, that are either obsolete or not present on the computer or server where the software is installed; or Worked on tasks that may have been beyond their competence. Software complexity Ultimately, software is created by human beings, and humans are fundamentally prone to make errors. As human beings develop software, it will be irrational to expect bug-free software and without any defect. Having said this, though, it is also a fact that any software that is developed to function for specific purposes is extremely complex and no single person can conveniently understand it. Each line of code can have thousands of possible inputs, outputs, states, or dependencies to deal with. We can say that it is possible to document every test case for every line of code, but we still cannot be sure that there is no unknown factor that can cause an error. A line of code is a part of a whole system, and the whole system needs to be tested to make sure that all parts of the application work correctly. All software are affected by external factors Software is a mindware that should adapt to external constraints. Conflicts brought about by external factors affect software quality. Issues like data formats unsupported by many operating systems, sheer number of different hardware and software configurations, different specifications of hardware and software components from third-party providers, and the like are not controlled by the company developing the main software. Handling and understanding all these external factors is complex, thus making the software prone to errors. The time and cost of development may increase due to adjustment processes to solve concerns and errors brought by external factors, such as: Server and hosting Compatibility with multiple browsers Integration with hardware Integration with third-party providers Integration with existing in-house systems Legacy data formats Scalability Government regulations The importance of software testing How does your IT supplier test? It’s important to understand and agree on how your IT supplier performs their software testing so that you don’t end up having to test the system yourself. Many companies employ freelancers who often do not have the infrastructure or time needed to test their own output. Besides, many people overlook mistakes when they are the ones who test what they have developed. The problem is, when you are the one who developed the system, you often test with the same data and in the same way. It is then easy to overlook mistakes which may have been more obvious to other people who were not part of the initial development. Testing should be done by people whose sole job is to test and are experienced in what they do. Firstly, they will be much faster at it. Secondly, their experience enables them to spot errors quickly and document them properly so the programmers can fix the bugs. A bit about automated and unit testing Complexity of software means that it’s impossible to test its every path. IT companies address this problem by implementing various processes such as setting up coding standards and using different testing methodologies. Automated testing is one practice that companies can implement to save time and do things faster. However, it is important to first consider the cost of its implementation before fully setting it up. If you update your software only once or twice a year, it will most likely be too expensive to develop automation testing unless if it’s for applications where the cost of errors is so high that they exceed the cost of developing automation testing. Automated testing is especially useful for software where you constantly make small changes and updates like 3-4 times a week. Besides, it is almost impossible to test system 3- 4 times per week, so it becomes necessary to automate testing. Programmers also incorporate “program bits” in their code that automatically test parts of the system—it’s a bit of a complex process, but it’s basically a piece of software that automatically validates another piece of software when it is delivered. If the results don’t tally, the programmer is notified of the error that needs to be corrected. Unit testing and automated testing are two components used in continuous integrations where a programmer, in the perfect world, simply has to press a button when he or she completes a task, then it is automatically tested and installed. How do you test effectively? You test every time a programmer has made a change or update to the system. Software testing is a task that takes time. It is a common mistake to not test enough or disregard the testing stage completely because testing is associated with expensive cost and too much time. This only results to struggling with mistakes and frustrating everyone involved in the project as it becomes even more expensive and ends up taking more time. Here are some methods available: Let users find and report the errors, although this setup may not be optimal unless the users are programmers themselves or are very technically-oriented. Use external software testers to review the completed system and report errors to be forwarded to the programmers, although this may be a time-consuming process as the testers are not part of the internal team. Use internal software testers who work hand-in-hand with the programmers—this is a very effective way to test. Automate testing so that the programmers can easily test what they have developed so far with just a press of a button. While this is also effective, it can be costly to program the software that performs the automatic test. Also, it’s quite difficult to automate frontend testing—while this can be done, it can be time consuming and expensive depending on the type of system involved. Changing requirements from the client Most clients or users don’t know what they want until they see it. The truth is, it is not until they start actually using the software, that they begin to understand what they need. Because of this, requirements and specifications constantly change throughout the development process, which can also contribute to the errors that crop up in the final development output. Studies have shown that an average software development project experiences about 25% change in requirements from the “requirements completion” stage to its first release. This is a common “scope creeping” problem that hampers nearly all projects. Commonly, users or system owners start to creep in new requirements when the first designs have been done. The design serve as visual basis for them to think more deeply on what they really want—and, thus, create changes. Changing any software requirement, even a small change, can have adverse effects. High level of interdependencies between the modules, makes the system error-prone. Here are some examples: The initial instruction of the client to its IT supplier is to develop a system where users must first register and log in. The system cannot be used by anonymous and unregistered users. One of the modules, DisplayProducts, is dependent in this log in process. DisplayProducts is a procedure that is used to display a set of products, based on the logged in user. After sometime, the client decided to change the initial requirement and asked its IT supplier to modify the system to allow anonymous users to use the website. Adapting to this requirement change, DisplayProducts procedure may fail because it has no basis on what products should be displayed, since users can now use the website without logging in. Originally, the client wanted Danish as the only language to be seen in the entire website. In the middle of development, the client requested its IT supplier to add English as an option. This change has major impact on user interface. As a result, some text labels may no longer fit in some parts of the web page, if the content in the new language takes more space than what has been anticipated and planned. The client wanted its IT supplier to develop an app that tracks distance of a vehicle. During the requirement gathering, it has been agreed that the unit of distance to be used is meters. ShowDistance procedure was developed to display the distance in meters. The distance output by this procedure is used in creating a report, showing the distance with the correct unit of ‘m’. At some point, the client wanted the app to be modified and change the unit of distance from meters to feet. If ShowDistance procedure was changed to show feet as the new unit of measure, and the report was not updated to show the corresponding unit of measure, the report will be incorrectly showing imperial values with metric labels. A module that calculates employee salary and produces a report has been working in the live server. The client gave additional information that should also be included in the salary computation. When this change was implemented, the module has been modified and tested, and it worked well in the development environment. However, when the system was deployed live, random crashing occurred. This was due to a server timeout caused by the additional processing required to handle the added information, and the amount of data to process. The development environment did not have enough data to trigger the timeout. Errors from misunderstandings Errors also arise from misunderstandings or miscommunications between the client and the programmer. Programmers can’t read thoughts, so you can’t expect them to understand everything that has to be done and how things are work in your industry without all the details being explained. There are things that may seem completely logical to you, but incomprehensible to programmers without your industry knowledge. Here are some tips to minimize these kinds of errors: Start by choosing an IT supplier who understands your industry. If you don’t know what you want, don’t start the project. It is very important that you know what you want out of the project before you even get started. Allow the programmer to write the specifications based on what you tell him or her. With this, there will be a "check and balance" and it will be easy to see if the assignment is correctly understood. Don’t say something like "We'll find out later" or "The programmer will know what to do when he or she comes to it" when you’re not sure yet on what you want to happen with the project. Surely, the programmer won’t know it if you yourself don’t. Avoid making a huge project at the outset. Split the project into phases as it will be easier for the programmer to understand what exactly should be done. You also reduce the risk of developing functionalities that end up not being used because after each phase, you have the opportunity to evaluate what will be part of the next phase, based on the things you learned in the previous phase. Last but not the least, communicate as clearly as you can. Misunderstandings can result to huge problems, but it can easily be avoided by proper communication. Bug-free software? There are no hard-and-fast rules to eradicate software bugs, and as you have read, there are many factors that come into play. However, this does not mean that IT companies should be complacent. At the end of the day, it’s the quality of their work—and their business—that’s at stake here. This is why software development firms observe processes, and put in place quality assurance or testing units. They also invest in tools and talents to catch errors, and ultimately improve the quality of the software they produce. Author Peter Skouhus A Danish entrepreneur who owns 1902 Software Development, an IT company in the Philippines where he has lived since 1998. Peter has extensive experience in the business side of IT development, strategic IT management, and sales.