Archive for the ‘Software Engineering’ Category

How Gmail Records Usage Statistics to Increase Conversions

September 12th, 2007 by Sameer | No Comments | Filed in Software Engineering

Recording statistics are good for any project.  You can do it on a macro level or a micro level.  Normally, we do it on a macro level (i.e. recording page hits for the entire site.).  However, we also sometimes use these same tools – say Google Analytics, to track clicks on certain buttons, etc.

How about building your application with such logic?  At a past company, we used this information to record which menu items were most frequently clicked.  Just a simple insert into the database on menu item click (web application).  This allowed us to find menu items that were infrequently clicked, and we reworded them or moved the more important ones to more visible locations.

The term conversion is used to mean something you are trying to achieve, say a sale, or a signup, or whatever it may be.  You can use this idea to monitor the effectiveness of your pages and increase conversions.  You can also use this to improve your user interface – say if certain menu items are rarely clicked, it could be a usability issue.

As well, Google applies this trick!  They monitor (or so it seems) their "Sign up" button, and they change it multiple times and monitor the effectiveness of each one.

Take a look at the different sign up buttons I have seen on GMail:

Gmail signup 1

This is the simple basic "Sign up for Gmail" link

Gmail Pick a name

This is the more fancy "Pick a name" link.

It’s sort of like their Google Adwords works, it allows you to set up ads to advertise your site or products, and allows you to monitor the effectiveness of that ad compared to the same ad say worded differently.

The general rule is collect as much statistics as possible, and then decide what you want to do with it.  You can always delete it if you don’t need it, but most likely it will be an eye opener for you.  You can then tweak your UI until you get it exactly how you like.  As well, to follow in the footsteps of GMail, you can use it to get more signups (or more generally known as "conversions") for your site!

 

Growing Pains of a Software Company

July 16th, 2007 by Sameer | 2 Comments | Filed in Software Engineering, Work Related

There is a particular small software company that has been in business for more than 10 years that builds a web application similar to say PHPNuke.  Here are a few characteristics of this company: They have survived this far using Microsoft Visual SourceSafe for their source control (which is probably okay for small teams but starts to have problems when you start to use it extensively), they have not used any unit testing, they do not have any form of automated testing or regression testing.  They have sales in the millions of dollars, and they have about 6-10 developers and 2 QA (as well as many QA overseas).  Every time a build is made, the overseas QA team has to "crash test it" (meaning to run the site and click frantically until something breaks).  This does not mean there is no test plan, but rather this method of testing is very unreliable and prone to errors.  As well the number of customers they have is less than 100, and we can reasonably assume that simultaneously less than 10 users would be logged in for each application.   Now that the company is growing each one of these issues is going to bite them in the butt. 

The boss might wonder, "if we got along this far without doing any of the following, well… why should we??".. But as a "soldier" on the front lines, you start to see the problems that can come up with this sort of thinking.

 

Not using unit testing

This means that QA receives a page that is not unit tested.  It is ad-hoc tested by the developer, meaning that they try to click and break their new code, but there is no form of automated manner to this testing.  As well, every time the code is updated, the developer has to re-test and re-re-test it manually.  As well there is no real confidence in the code other than the fact that the QA team has tried their best to crash it and it did not crash.  It might even be very time consuming and painful to set up the test each time.  Without unit testing, this is a lot of time wasted that could be used in development. Read up on Test Driven Development for something else that you can gain from proper Unit Testing.  By the way, what does unit testing software cost you?  FREE if you use NUnit.  Or like $14,000 if you use IBM Rational Test RealTime. Its up to you. Just Do It.

 

Not using proper Source Control

Trying to implement branching ,sharing, multiple releases, with Visual SourceSafe! You will find it is very difficult.  As the company is growing they needed to be able to release and develop multiple versions concurrently.  This is near impossible with SourceSafe, if not very difficult, and they need to move into using a better source control software such as Team System, Subversion, Perforce, etc..  This will give them features such as atomic checkins, shelving (if required), cheap labels, etc..

 

Not using automated testing

This comes back to the earlier topic of unit testing…  Without automated testing, there is no confidence in the code.  Each change, even a minor one, can possibly break some unknown piece of code in the system. 
To hear a real story, making a change to a general object in the system caused a crash on a Report that was only somewhat related to the general object. 
 
This was not noticed until on a live customer demo, but due to slickness on the part of the presenter, it was overlooked.  This is a deadly game of cat and mouse, that can result in lost customer confidence and eventually lost customers.  AUTOMATED TESTING is FAR TOO IMPORTANT to not use, especially if your company is growing and growing.

 

Small number of customers

With a small number of customers, there are some problems that you have in your code that will not be noticed until you start to grow.  For example, if your code is not thread safe, and you are using shared/static variables that are not meant to be shared on a specific page, problems that might not show up until you have multiple users loading that page simultaneously.  This will happen as your number of customers grow.
 
 
As well as load issues.  As a small shop, you can throw the most horrible piece of inefficient code and in most cases it will not cause a problem because your server can most likely handle it.  As you start to increase in size as a company, and as you have more people hammering your server, your inefficient code is going to start to tear at the seams and you will have to go back and re-organize it.    Sometimes code can survive and be in use for more than 5 years so its well worth your time to build it properly.   Look at your own code set and see how old it is.  If it’s been years and years and you are still using it, re-consider that the time you spend to build it properly is well worth it.  Tell your boss to make sure he knows who he is hiring, as bad apples can spoil the whole pie.

Are You a Sharp Developer?? (Part 1)

July 11th, 2007 by Sameer | 6 Comments | Filed in Software Engineering, Work Related

Many studies have shown that there is a 10 to 1 difference between good developers and bad developers.  How can you become a better developer?  Well,  there is many things you can do, and this is how you can improve your quality, and therefore get more return on your investment in terms of better jobs, and you can also be more selective about the jobs you take. 

1. Improve your communication skills – both speaking and writing.

One of the most important things you can do to become a better developer is to improve your communication skills.  This is a win-win situation.  You will find you will be able to better relate to others, to your boss.  You will find that you can explain yourself (or maybe defend yourself) against your boss and colleagues.  You will be able to knock them out in interviews even if you don’t really know what a deconstructor is or how on earth to deconstruct your class.

2. Constantly learn and improve your skills and yourself

You can only become a better developer if you are constantly learning.  The world is changing so fast, that you need to be constantly reading books, articles, going to conferences, and asking from others.  An easy way to do this is to find some nice sites you like, and subscribe to their RSS feeds on GMail or on your favourite RSS reader.  Make sure you always have a book by your side.  Even if its not a technical book, develop yourself personally.  Find out your weaknesses and improve them.  For many of us that might be our presentation skills, so build those skills!  Practice talking infront of a mirror or to yourself.  I have made so many suggestions to our current process just by keeping up on .NET blogs.  It will make you stand out from the rest of the crowd.  For example I suggested converting our site to a Web Application Project which will allow us to do tons of things like get a build script (automate our build process), break our project into multiple subprojects, etc, etc..

3. Share your knowledge and experience

There are different ways to do this.  Don’t think that keeping everything to yourself is going to help you.  Infact, sharing your knowledge and experience with others always pays off.  Don’t be stingy, and you will find much in return.  One way to do this is to once a week email your co-developers with some ideas on how to improve the code quality.  Another idea is to start a blog!  This will also result in an exchange of ideas and your bad ideas will be weeded out.   You can also contribute to forums or start a discussion.  If you aren’t willing to do this, you might think you are the smartest piece of cake until you realise just how shallow your ideas are when you discuss with others.

4. Learn from your mistakes

Back when I was doing my first web development job (4 month internship), I decided to make some changes to the ASP application.  However, I did not make any backups.  Let me tell you I learned really quickly to always make a backup.  Don’t be bit from the same snake hole twice! Learn from your mistakes and grow as an individual.

What are some of the other benefits to becoming a sharp developer?

Positive and Negative Testing in C#

June 27th, 2007 by Sameer | No Comments | Filed in .NET articles, Software Engineering
In testing, there are two complementary concepts we need to understand–positive testing and negative testing.
 
For the sake of this example, positive testing refers to testing that things do what they should–for example, if you calculate the sum of two numbers, does it return the correct sum? Does sum(1, 2) return 3?
 
Negative testing refers to testing that things don’t do what they shouldn’t–for example, if you try to calculate sum("test", 4) you shouldn’t get a valid result!
 
The key to remember is positive and negative testing, together, give you comprehensive coverage of functionality–you’ve verified that the program does what it should do, and only what it should do, no more. There is no margin for ambiguity.
 
To clarify this, let’s jump to some code. Say you had a function that returns the greatest common denominator of two numbers:
public sealed class ExtendedMath
    {
        ///<summary>
        /// Find the greatest common denominator of two numbers.
        /// Note this is based on the Wikipedia pseudocode.
        /// eg. findGcd(6, 8) will return 2
        ///</summary>
        ///<param name="a">The first number</param>
        ///<param name="b">The second number</param>
        ///<returns>The GCD of a and b</returns>
        public static int FindGcd(int a, int b)
        {
            int t;

            while (b != 0)
            {
                t = b;
                b = a % b;
                a = t;
            }

            return a;
        }
    }
}
Now, to do some positive testing, you need to verify the function works. You might write the following:
            Debug.Assert(ExtendedMath.FindGcd(6, 8) == 2);
            Debug.Assert(ExtendedMath.FindGcd(3, 4) == 1);
            Debug.Assert(ExtendedMath.FindGcd(27, 27) == 27);
            Debug.Assert(ExtendedMath.FindGcd(3, 21) == 3);
(For the sake of berevity, we omitted writing actual NUnit test-cases.)
 
If you wrote those "tests", well and good–you’ve now tested that the GCD function returns what it should, given some sort of input. Note you have a few interesting cases–the second case, when the GCD is one; the third case, when the two numbers are equal; and the fourth case, when one of the numbers is the GCD.
 
In fact, by now, you’re probably feeling a little smug–only six lines of code to calculate the greatest common denominator of two numbers!
 
Now, let’s get a little fancy, and write a form that’ll take in two numbers in input-boxes (uxA and uxB) and a button (uxCalculateGcd), and show the GCD in a pop-up, like so:
 
 
And the code for the button:
 
public partial class GcdView : Form
    {
        public GcdView()
        {
            InitializeComponent();
        }

        private void uxCalculateGcd_Click(object sender, EventArgs e)
        {
            int firstNumber = int.Parse(this.uxA.Text);
            int secondNumber = int.Parse(this.uxB.Text);

            int result = ExtendedMath.FindGcd(firstNumber, secondNumber);
            MessageBox.Show(string.Format("The GCD of {0} and {1} is {2}", firstNumber, secondNumber, result));
        }
    }
If you try this with -8 and 12, we get the message "The GCD of -8 and 12 is 4", which seems correct. But what if we try this with 8 and -12? The function returns -4! Can -4 be the GREATEST common factor of 8 and -12? No, because 1 is always the common factor!
 
AHA! There, we’ve stumbled onto something–we’ve tested the function with input outside of its valid range, i.e. written a negative test!
 
To fix this, we should modify our function to return 1 if either of the numbers are negative, like so:
 public static int FindGcd(int a, int b)
        {
            if (a < 0 || b < 0)
            {
                // Not valid input
                return 0;
            }

            int t;

            while (b != 0)
            {
                t = b;
                b = a % b;
                a = t;
            }

            return a;
        }
(New code indicated in bold)
 
Now, running our function with these values gives us 0. (To be smarter about it, we could do some checking in the GUI and show an error-message if either number is negative; or we could apply some Debug.Assert statements into the beginning of the function to ensure that the input values are 0.)
 
What about if we enter 23 and "test"?   We get a FormatException, like so:
 
 
(To write this as a test case, we would have to set the text-box text, hit the run button, and catch a FormatException; if the exception wasn’t caught, then the test should fail.)
 
And that’s positive and negative testing in a nut-shell, the Sharp Developer way!

 

Mock Objects for Dependencies

June 23rd, 2007 by Sameer | No Comments | Filed in Software Engineering

By Ashiq Alibhai

Automated testing is a where developers write test-cases (via code, or some sort of action-recording device) which they can then run later at the click of a button. This code (test case) typically sets some things up, does some sort of action, then verifies the outcome against an expectation. Done en-mass, a proper selection of test-cases can help developers and quality-assurance test almost the entire application with little effort.

One question that often comes up with automated-testing is how to create independent tests—tests that don’t require more then one module. For example, if you have a login page, which pulls data from a database, how can you test if the login page is working without depending on the database working?

Enter "mock objects"–mock objects are used to mock expensive or hard-to-create resources. For example, you can create a "mock" database that always returns the same data, pretends it’s deadlocked, and so on—without the overhead of having a real database.

And this is one of the powers of mock objects—you can use them to eliminate dependences between different modules! If your application needs to connect to a database, grab XML from a remote server, and pull up a file from the file-system, then correlate the data—use mock-objects to eliminate the need of those modules to be working correctly. Simply return usable data, and test!

And of course, one of the drawbacks of mock objects is they’re not real—that cases may arise where the mock object is too fake, and although the test cases pass, the application fails on real data.

Mock objects are a tool, just like any other tool; and they can be used for good or for evil. Be wise, and make sure you understand what you’re mocking when you create your mock objects.

An Insider’s Look at Microsoft’s Software Testing

June 22nd, 2007 by Sameer | No Comments | Filed in Software Engineering

A lot of people dream when they think about working at Microsoft – You get free pop, right?  Well, not really.  More than that, you are building software that is used the world over, influences millions, and has huge worldwide impact.  Plus it doesn’t hurt that it pays well to work for Microsoft.  Imagine if you are building the .NET framework, you are building a tool that is used to build tools for the world.

 

Did you ever want to take a look inside Microsoft to see how they build and test these puppies?  Here is a brief glimpse at how important quality is to Microsoft, and how hardcore their testing is:

 

Microsoft supports all software for at least 10 years after the date of its release.  For testing ASP.NET 2.0 and Visual Web Developer, they have ~105,000 test cases and ~505,000 functional test scenarios covered Their team has approximately 1.4 testers for every 1 developer.  Why? Because, They take quality pretty seriously at Microsoft, and because they have a lot of very hard requirements that necessitate careful planning and work to ensure high quality.

 

Also, Microsoft built their own in house testing software called "MadDog".  MadDog runs on 1200 machines and will identify free machines in the lab, automatically format and re-image them with the appropriate operating system, install the right build on them, build and deploy the tests selected onto them, and then run the tests.  Wow!  Here is a picture-

 

Now everyone knows there is a running joke about Microsoft software, how buggy it is, you know, blue screen of death, right?

Read more about it at  Testing ASP.NET 2.0 and Visual Web Developer

 

Are you really testing your code properly?

No Silver Bullet vs. Agile Software

May 30th, 2007 by Sameer | 1 Comment | Filed in Software Engineering

In 1986, Frederick P. Brooks published No Silver Bullet, a small treatise that makes an important distinction in terms of software development–between accidental difficulties and inherent difficulties.

Accidental difficulties are things like a slow compiler, a difficult language syntax, etc. — things which can, by and far, be surmounted by technology, eventually–faster CPUs, more memory, and everyone’s happy!

Inherent difficulties, on the other hand, deal with difficulties inherent to software that will not be overcome by technology.  Things like software complexity, good design, integration of complex parts, and so on.

While Brooks makes some good points, we can extract, from his article, why Agile Software methodologies increase the success rate of software projects by a great degree.

Complexity: Software is made up of multiple differing and complex parts.  System-wide complexity is difficult to overcome.  The larger a piece of software becomes, the more complex.  Agile software solves this by using architectural spikes and iterative design–only the minimum necessary architecture comes out, and iterative design keeps the relative complexity low.

Conformity: Software is made up of multiple different parts and offers many different interfaces to mesh–between two classes, between interfaces, between users and the system, between the system and the underlying OS.  Agile software solves this with early integration and iterative usability testing, where integration between different parties becomes resolved very early on.

Changeability: Software, once released, comes under pressure to change–change from external users, from coders, from testers, from stakeholders.  Agile software solves this with iterative development which includes refactoring and burn-down–so architectural changes get implemented and bugs get fixed, before problems can grow and expand.

Invisibility/Abstraction: Software deals with invisible and abstract entities–classes, interfaces, delegates, database query plans, pointers–concepts that take serious brain-power to comprehend.  While not unique to agile software, agile software solves this with UML diagrams, class diagrams, and other concrete geometrics.

So while there may be "no silver bullet" in software development, Agile Software methodologies provide a strong and compelling base from which to deal with the inherent complexities of software development.

By Ashiq Alibhai