Software Testing Tips
 
Published: 27 Jul 2010
Abstract
In this article Brendan introduces several tips that you can use in your unit testing endeavors. He demonstrates how tests can be used as documentation, discusses the right number of tests to write, and emphasizes how test code should be maintained as well as regular code. Brendan succinctly delivers several other tips regarding software testing as well.
by Brendan Enrick
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 40329/ 60

Introduction

Testing is an important practice for software developers. There are plenty of reasons to write tests and maintain them. In this post I've aggregated a collection of blog posts of mine, which cover some tips for testing software.

References

·         Time-Tested Testing Tips - Part 1

·         Time-Tested Testing Tips - Part 2

·         Time-Tested Testing Tips - Part 3

Tests as Documentation

I've said plenty of times in the past that the tests you write become excellent documentation which can be used to demonstrate how different aspects of your system should be used. This is very useful for someone joining a project. If it is well-documented in its tests, learning how to work with the code is as easy as reading through the tests and seeing how the different objects are intended to interact. If you can't do this, you're probably not testing well.

A good measure of your application's testing is to have someone learn to use the system based solely on the tests. If the tests are written well enough, someone will be able to figure out how everything works and interacts.

This is one of my primary goals when testing an application. I want to make sure that things are clear, because when I come back to this code a month from now I will be that new developer on the project. I will need to know how to use the classes, interfaces, etc. and having it documented in working cases goes a long way.

How many tests should I write?

This is one of the most common questions asked by new testers. For now I will take the cowardly approach and say, "it depends". I've read posts from people touting the number of tests they've written. This is a new metric as if "line count" wasn't already bad enough. There is a balance here that we are looking for. Just with the line count.

If your line count is small you're application probably doesn't do very much and if it is large then your application might be cumbersome and difficult to maintain. When you don't have many tests your code is more prone to errors, but if you've written too many tests maintainability disappears. But wait! Didn't I say earlier that tests make code more maintainable. Well, yes I did, but if you write too many it becomes difficult to change the code. If you test every single possible minute little thing in your application you're going to have a heck of a time changing anything.

When you're writing tests make sure you have just enough to give yourself confidence that your code is working.

I highly recommend against ever setting code coverage or test count goals. If you set goals for these you're just creating incentives to write more tests than is required. Too many tests can create the same problems as too much code. Why? Because tests are code.

Test Driven Development

Yes, I am going to bring this up. Plenty of people have latched onto the idea that testing code helps make code better. A lot of people even believe that it makes the process of writing the code faster. I see a lot of people who are reluctant still to use test driven development. I know I am throwing around a buzzword… or maybe I mean buzzphrase since that’s actually three words.

I don’t plan on doing TDD justice here since I am trying to keep these tips relatively short. I just hope this is enough to inspire people to go read, learn more, and try some test driven development. I am going to give some quick reasons why developers testing their code should write the tests first.

·         You will not want to go back and write it later. Sometimes you are going to go back and write the tests for the code you have already written, but what happens if you decide you’re going to write a lot of code and then go back and add the tests. Now you’re talking about a lot of testing all at once. There is a good chance you’ll cut corners and maybe skip entire aspects of the testing. I know I would be tempted.

·         How do you know what kind of interface your new code needs if you’ve never used it? If you start by trying to use some code that does not exist yet, you’ll be deciding how you would want to use it. Now you’re probably thinking you could do that anyway. If you write code to use some new feature you will know the design is easy to use and work with. You just made it up and used it in the test. If you didn’t write the test you had to guess what interface you will want later.

Organize, Refactor, and Take Care of Your Tests

I recommend you repeat this daily, “My test code is just as important as my production code”. I think this is a very good point to remember when you’re writing tests. All of those principles you apply when writing production code should be followed with test code. DRY, SOLID, YAGNI, etc. are all important even with the testing code.

Obviously duplicating code can make your tests difficult to maintain. What if some business logic changes? If you were repeating yourself you now have the fun task of going through a dozen tests changing each one, but if you had not repeated the same code you might have been able to update one location in the test code. A lot of people are concerned when the line count of a single file gets large and they will refactor it into multiple manageable files. This same policy should apply to test classes. If you’ve ever gone into a test class with way too many classes, you probably know how difficult it can be to maintain.

Tests exist to make development easier, and if they become difficult to maintain then something needs to change. I certainly don’t advocate spending large amounts of time refactoring the tests, but since they are supposed to increase the longevity of the application they must also be maintained.

Adjust Your Style to Your Test Framework

I obviously recommend that everyone use a testing framework. There are plenty of them out there, and they supply a great deal of the tools you’ll need for testing. They come in all languages, flavors, and colors. You might look into these NUnit, MSTest, JUnit, CppUnit. What is important is that you make sure you know how your tools work so you can test best with them.

I will elaborate on a couple of examples and perhaps down the road I’ll give some more specific examples.

Some tools show you a list of test names, and only minor details about why the test failed. For this you usually need to go the description view or something similar. In these cases it is important to name your tests effectively.

As an example if I have a method called Add and it takes two parameters a and b. I might write a test for that method. If I name my test TestAdd, and that test fails you know something is wrong in that method, but you do not know what failed. If I had instead made a few more specific methods you could glean more information from the test having failed. Some examples of tests I might create are AddTwoZerosShouldBeZero, AddNumberToZeroShouldBeTheNumber, AddPositiveNumbersTest, AddNegativeNumbersTest, etc.

Some parts I would lump together like positive numbers and negative numbers. It is important to handle a couple of different scenarios as well as the edge cases. I could have done negative and natural numbers and that would cover all numbers, but I wanted to make sure the edge case, zero, was handled correctly, so I test it separately.

People can argue back and forth all day long about whether you should have a lot of small tests or group them together, but this is what has worked well for me in the past and I hope it works well for you also.

Keep Test-Relevant Details Visible

I've said in the past to treat test code just like any other code. However, there are a few reasons to break from this rule. One is the context switching which will be caused by extracting information which is important to a test. Let me explain what I mean with two examples.

Example Using Helper Method

[Test]
public void CalcInterestRoundsToTenthPennies()
{
    decimal initialMoney = 100.00;
    decimal expectedInterest = 33.333
    InterestCalculator ic = GetTestInterestCalculator();
    
    decimal actualInterest = ic.CalcInterest(initialMoney);
    
    Assert.AreEqual(expectedInterest, actualInterest, 
      "CalcInterest did not round to a tenth of a penny correctly");
}

Example Without Helper Method

[Test]
public void CalcInterestRoundsToTenthPennies()
{
    decimal initialMoney = 100.00;
    decimal interestRate = 0.3333333333;
    decimal expectedInterest = 33.333
    InterestCalculator ic = new InterestCalculator(interestRate);
    
    decimal actualInterest = ic.CalcInterest(initialMoney);
    
    Assert.AreEqual(expectedInterest, actualInterest, 
      "CalcInterest did not round to a tenth of a penny correctly");
}

Notice here that you can tell a lot more about what is going on in the second one, because you know what percentage is being used to calculate. You cannot tell that the first one is accurate since you can't see the percent. I recommend trying to keep the amount of values to a minimum and if you're writing your code well you'll have few enough dependencies that you will not have a problem. These helper methods as you can see make it so you will need to go to another location to see what was initially created. In some instances they are useful, but use them sparingly as they might hide details.

Do Not Unit Test Third Party Frameworks

Make sure that what you're testing is part of your code and not someone else's. If you're testing code you have no access to you better not be keeping that around as an automated test. You're wasting your time if you're creating automated tests for this code. If you find a bug in the code you can tell someone about it, but you probably can't fix the code. If it is an open source project you're testing then go test the code in their test library and fix issues you find. You will be doing them and yourself a favor. Don't clutter your own test library.

Write Automated Tests Whenever You Are Curious

If I ever wonder how some piece of code or a class works or something, I could go write a simple application and test something out. I certainly do not waste my time though. It tends to be much faster just to write a test to answer my question or learn something new. If I want to try something out I just write a test. If it is an internal piece of code I go look at the existing tests, and if it is not I write a temporary one just to try something out.

Unit tests are quite useful for this sort of thing, and since I have keyboard shortcuts mapped to run them they're very fast. If you really want to test a lot, you need to start using them all the time. They become very easy to come up with and write once you practice them enough.

Conclusion

Testing isn't hard to learn, it is hard to master. Remember that testing is about designing great, maintainable, working software. If you're just testing to test, you're going about it the wrong way. Testing is a powerful tool, but it is also a great strategy for designing excellent software. Keep designing your software through testing, and you will see what I mean.



User Comments

Title: QA Manager   
Name: Sami Ullah
Date: 2010-10-22 3:08:04 AM
Comment:
Hi ! These tips are really useful.
Title: SOA Testing   
Name: SOA Testing
Date: 2010-09-06 1:17:21 AM
Comment:
Hi.
These tips are very useful one It contain very important detail Its really a fantastic things for me
Title: Software Testing   
Name: SOA Testing
Date: 2010-08-23 4:15:48 AM
Comment:
Wow..These are really a great tips it will useful for me I like it very much.
Title: SQA Services   
Name: SOA TESTING
Date: 2010-08-10 2:08:58 AM
Comment:
Hello..
Wow great post you have give us wonderful tips It will useful for us.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-16 2:06:53 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search