Tuesday, October 27, 2009

12 Practical Tips for Building Bug-Free Software

Does your software application have bugs? Of course it has, every software application that’s out there has bugs and bug-free software is a myth. But it’s still possible to greatly minimize bugs, security problems and errors in your application by following a few tips and techniques I outline in this posting.

Recent studies show that up to 40% of system failures are caused by software bugs and that common memory and concurrency related bugs account for 60% of system vulnerabilities and security problems. So reducing software bugs in your application is the best way to increase the stability, reliability and security of your software.

Here is list of 12 practical tips for building bug-free software (or at least software with fewer bugs):

1. Code Reviews

Four eyes see more than two. That’s why you should let other developers review your source code on a regular basis. Pair programming on the other hand, a technique where two developers write code together for longer periods, isn’t for everyone and is often not needed. But complicated, important or security related code greatly benefits from code reviews and will improve your code quality a lot.

2. Beta Tests

Beta tests play an important role with keeping your software’s quality high. But most times, it doesn’t make sense to release beta versions of your software for minor updates. Major releases on the other hand, should be tested by end-users and customers before going gold. You can test your software as much as you want, if you cannot control the execution environment, the chance is high that end-users will find bugs and problems with all the different computer configurations out there. Also make sure that your software reached a high quality standard before giving it to beta testers. You don’t want to waste the testers’ time by letting them find and report bugs that you already know about.

3. Automated Tests

Automated tests like unit tests or automated GUI tests can be used to guarantee the functionality of application modules, application programming interfaces (APIs) and user interfaces. You don’t have to be a test-driven development wizard to make good use of automated tests. Using unit tests for key parts of your application can go a long way towards building more reliable software. There are tons of unit testing frameworks, web and GUI testing tools out there that you can utilize.

4. Logging

Using log files or live logging during development and production usage is an important and useful technique to identify bugs, find concurrency problems and to analyze and find out why an application crashed. Advanced logging tools are also able to log complete objects, trace threads and distributed systems and offer rich viewer tools to monitor your application. Instead of writing your own basic logging framework, you should use proven and advanced libraries and tools. Many open-source and even some commercial offerings have been released over the years, including .NET, Java and Delphi logging tool.

5. Error Reporting

To find and resolve errors and exceptions, you first have to know what kind of errors your users and customers are experiencing. Many users of trial software won’t get in touch with you to report any errors. Instead, they will just uninstall your application and test a competing product. To make error reporting for end-users easier and more useful to you, you should use automated error and exception reporting techniques. When an unhandled exception occurs, your application should show a friendly dialog offering the user to send an error report back to the developer. Error reports should contain all kind of information to help you identify the problem, including error messages, call stacks, version numbers and log files.

6. Customer Feedback

Similar to error reporting, you should make giving feedback as easy as possible for your users and customers. You can also use a short (optional) survey when a user uninstalls your application. This survey should only have a few questions and besides other things ask why the user uninstalled your software. If a lot of users report that they uninstalled your software because of stability problems, you will know that your application isn’t as high-quality as you have thought.

7. Use Proven Code

You should build the core functionality and main features of your applications yourself, because only then are you able to easily and quickly modify and improve it. But for many other parts you can reuse existing and proven code. It will take you years to build a stable, easy-to-use and feature complete reporting engine or setup builder, for example. Often times it’s better to use proven existing code, either from internal libraries, third-party companies or open source solutions if the license permits this.

8. Dedicated Testers

If possible, you should have dedicated testers in your organization for quality assurance. In fact, you should have lots of them. For simple standard applications, one tester per developer is a good rule of thumb. For applications that are complicated and time-consuming to test, two or more testers per developer are needed. Many small organizations cannot afford dedicated testers. If this is the case, developers should test each others’ code. It’s important that others test your code and functionality, because general wisdom says that developers do a really bad job testing software that they wrote themselves.

9. Virtual Machines

To test your software on as many different environments and operating systems as possible, you should use virtual machines with tools like VMware, Virtual PC or other available virtualization software. Besides allowing you to test your software on all kinds of configurations, you will save tons of time because you can easily copy, share and reset the virtual machines. It’s a good idea to create many different standard images for all the operating systems you regular test on and put them on a file server. When you need a specific configuration to test something, you can then start with one of your base images without installing the operating system, drivers and required software and so on.

10. Write a Specification

Many bugs are caused by badly designed class hierarchies, inaccurate interfaces, wrongly understood requirements and the therefore required workarounds. That’s why an experienced developer or architect should write a specification with all the collected requirements and technical implementation details before writing the first line of code. But as always, requirements change during the lifetime of a software application. That’s why it’s important to keep the specification up-to-date and plan the architecture changes for any new or altered requirements.

11. Use a Good Debugger

If you use an IDE like Visual Studio, Eclipse or Delphi, you already have access to a powerful debugger that you should use. But with many development environments and development platforms like PHP, Windows Scripting, Python and Ruby, many developers aren’t using a debugger. In those scripting environments, developers often try to squish bugs by try and error, changing code parts, adding a few print statements and so on. This is not only a very cumbersome and time-consuming way of identifying and solving bugs, it’s also very dangerous if you don’t fully understand your code and are able to step through it with a debugger. Do yourself a favor and get a good debugger for your development platform (and there are debuggers for almost everything).

12. Debug and Strict Options

Many development environments allow you to enable special debugging options like range checking, overflow checking and memory corruption checking. Such options should be enabled during development and sometimes even during quality assurance to identify hard to find bugs. Many script languages like Perl or PHP on the other hand allow you to enable certain rules and warnings that will force you to declare variables before using them. This is especially useful if a script language is case-sensitive and it’s easy to make typos.

How to Scope your Projects

The "project scope" is all of the things that must be produced to complete a project. These 'things' are called deliverables and you need to describe them in depth as early in the project as possible, so everyone knows what needs to be produced. Take these 5 Steps to scope your projects:

Step 1: Set the Direction
Start off by setting the direction for the project. Do you have an agreed Project Vision, Objectives and Timeframes? Are they specified in depth and has your customer agreed to them? Does everyone in the project team truly understand them and why they are important? Only by fixing the project direction can you truly fix the project scope.

Step 2: Scope Workshops
The best way to get buy-in to your project scope is to get all of the relevant stakeholders to help you define it. So get your project sponsor, customer and other stakeholders in a room and run a workshop to identify the scope. What you want from them is an agreed set of major deliverables to be produced by the project. You also want to know "what's out of scope".

Run the workshop by asking each stakeholder for a list of the deliverables they expect the project team to deliver. Take the full list of deliverables generated in the workshop and get them to agree on what's mandatory and what's optional. Then ask them to prioritize the list, so you know what has to be delivered first.

Step 3: Fleshing it out
You now have an agreed list of deliverables. But it's still not enough. You need to define each deliverable in depth. Work with the relevant people in your business to describe how each deliverable will look and feel, how it would operate and how it would be supported etc. Your goal here is to make it so specific that your customer cannot state later in the project that "when they said this, they really meant that".

Step 4: Assessing Feasibility
So you now have a detailed list and description of every deliverable to be produced by your project, in priority order and separated as mandatory / optional. Great! But is it feasible to achieve within the project end date? Before you confirm the scope, you need to review every deliverable in the list and get a general indication from your team as to whether they can all be completed before your project end date. If they can't, then which deliverables can you remove from the list to make your end date more achievable?

Step 5: Get the thumbs up
Present the prioritized set of deliverables to your Project Sponsor and ask them to approve the list as your project scope. Ask them to agree to the priorities, the deliverable descriptions and the items out of scope.

By getting formal sign-off, you're in a great position to be able to manage the project scope down the track. So when your Sponsor says to you in a few weeks time "Can you please add these deliverables to the list?", you can respond by saying "Yes, but I'll either have to remove some items from the list to do it, or extend the project end date. Which is it to be?". You can easily manage your Sponsors expectations with a detailed scope document at your side.

The scope document is the Project Manager's armor. It protects them from changes and makes them feel invincible!

Paypal Integration

The Basics:

- After shopping all the required items and filling up the checkout form when the "Order" button is clicked, the customer is taken to the paypal website wherein the customer is prompted for either payment through paypal account or through credit card (if not having a paypal account).

- Now during this redirection from checkout page to paypal website, we need to collect/prefill some values that are required on the paypal website. And these values has to be collected/filled in certain pre-defined "html hidden form variables" termed as "paypal form variables". So we have to put an intermediary page between checkout page and the paypal page where these values can be collected.

- The following is the list of paypal form variables:

<form name="order" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">

* <input type="hidden" name="cmd" value="_ext-enter">

* <input type="hidden" name="redirect_cmd" value="_xclick">

* <input type="hidden" name="business" value="testgods@gods.com">

<input type="hidden" name="no_note" value="1">

<input type="hidden" name="no_shipping" value="0">

<input type="hidden" name="first_name" value="FirstName">

<input type="hidden" name="last_name" value="LastName">

<input type="hidden" name="address1" value="Address1">

<input type="hidden" name="address2" value="Address2">

<input type="hidden" name="city" value="City">

<input type="hidden" name="zip" value="PostCode">

<input type="hidden" name="country" value="Country">

<input type="hidden" name="email" value="Email">

* <input type="hidden" name="currency_code" value="USD">

* <input type="hidden" name="item_name" value="Your testGods order">

* <input type="hidden" name="amount" value ="OrderAmount">

* <input type="hidden" name="test_ipn" value="1">

* <input type="hidden" name="rm" value="2">

<input type="hidden" name="notify_url" value="http://192.168.101.90:8013/Thanks.aspx">

<input type="hidden" name="lc" value="GB">

<input type="hidden" name="cbt" value="Click Here to Complete Order">

* <input type="hidden" name="return" value="http://192.168.101.90:8013/Thanks.aspx">

<input type="hidden" name="cancel_return" value="http://192.168.101.90:8013/Cancel.aspx">

<script type="text/javascript" language="JavaScript">document.order.submit();script>

form>

From the above list, the fields marked as * are the minimum required fields. Out of which the "test_ipn" variable is required only during the test mode. When making live this variable should be removed. In the

tag, the value action="https://www.sandbox.paypal.com/cgi-bin/webscr" - this url is meant for test mode. When making live this url needs to be changed to action="https://www.paypal.com/cgi-bin/webscr". The testing environment is termed as "sandbox environment".

Sandbox Environment :

- Now, as mentioned in the very first sentence when the customer is taken to the paypal website - the customer is prompted for either payment through paypal account or through credit card (if not having a paypal account).

- During sandbox environment we have to create some test accounts such as "personal" accounts and "business" accounts. A “Personal” account means the customer accounts that can make payment through paypal during sandbox environment. "Business" account means the client account/merchant account from whom the customer is purchasing the products.

- In order to create "personal" and "business" accounts we need to signup with https://developer.paypal.com. After signing up with developer.paypal we can create/manage sandbox accounts using this login account.

- To create/manage sandbox accounts (i.e. personal and business accounts) login to https://developer.paypal.com.

- You can get information on how to create sandbox accounts from - https://www.paypal.com/en_US/pdf/PP_Sandbox_UserGuide.pdf

- Whenever a new "personal" or "business" account is created an e-mail is fired. This e-mail contains a confirmation link, by clicking on this link only the account is activated. As soon as we login to https://developer.paypal.com. we can see various tabs such as "Home”, "Sandbox", "Test Certificates", "Email" . We can access the e-mails by clicking on the Email tab.

- After creating a "personal" or "business" account, the next step is to "Add a Bank Account" and then "Add a Credit Card" for the "created"

account(s).

- To add a bank account or a credit card we need to login to the respective "personal" or "business" account. After signing in

Navigate to My Account > Profile. Under the Financial Information header, click the Bank Accounts link or Credit Cards link.

- While adding a bank account there are certain things to be kept in mind for some specific countries.

(Reference - https://www.paypal.com/en_US/pdf/PP_Sandbox_UserGuide.pdf)

- While adding a credit card, only add Visa cards.......because only VISA cards are valid in test mode.

- A credit card may have limitations of transactions upto certain amount. After that we need to add a new credit card number for that particular "personal" account.

- Imp : We need to have test credit card numbers to test the transactions for those who don’t have paypal account. To create such credit card numbers, login to any of the "personal" account created in sandbox - go through the normal process of adding a credit card. But most imp. thing to be kept in mind is that as soon as the auto-generated credit card number is displayed, just make note of that credit card number and don't click on the "Add Card" button.......instead click on "Cancel" button otherwise that particular card number will be valid for that particular personal account and not available for non-paypal account holders. And this auto-generated credit card number can be used to test transactions for non-paypal account holders.

- Note : While running the application in test mode you need to keep an instance of https://developer.paypal.com opened in a separate browser and also needs to be signed in with the login with which sandbox accounts were created. And need to check every 10-15 min. whether the session has expired. During test mode enter any of the "personal" accounts created in sandbox i.e. enter any of the personal account email id and password to do the transaction in test mode.

Making Live:

Following things need to be kept in mind :

1) Remove the "test_ipn" variable from the list of “paypal form variables".

2) In the tag, change the value of action="https://www.sandbox.paypal.com/cgi-bin/webscr" - this URL is meant for test mode. When making live this url needs to be changed to action="https://www.paypal.com/cgi-bin/webscr".

3) Change the value of the variable named "business" to the original value.