Lesson 3: Creating a Unit Test Plan

Lesson 3: Creating a Unit Test Plan

Once you complete the code for your application, you should test it to ensure that it functions according to specification. Although the compiler detects syntax errors, run-time errors and logical errors might not be revealed without thoroughly testing your program. In this lesson, you will learn how to design an efficient test plan for your component or application. Additionally, you will learn how to create a multicultural test environment and how to provide multicultural test data to your application.

After this lesson, you will be able to

  • Describe how to create a test plan for your classes

  • Explain how to create a multicultural test environment for your application

  • Describe how to provide multicultural test data to your application

Estimated lesson time: 30 minutes

The Unit Test Plan

Most code contains errors when first written. Thus, you should expect your code to have bugs when first written. However, a final application that is full of bugs or does not function according to specification is useless. You create a final version from a bug-laden first draft through testing.

Testing and debugging are separate but related activities. Debugging refers to the actual finding and correcting of code errors, whereas testing is the process by which errors are found. Testing is usually broken down by method. Individual methods are tested with a variety of inputs and execution parameters. This approach is called unit testing. Most applications are too complex to allow every possible variation of input and run conditions to be tested. Indeed, consider the following method as an example:

Visual Basic .NET

Public Sub DisplayName(ByVal Name As String) System.Windows.Forms.MessageBox.Show(Name) End Sub

Visual C#

public void DisplayName(string Name) { System.Windows.Forms.MessageBox.Show(Name); }

Assume that the method that calls DisplayName limits the size of the Name parameter to eight characters and allows only the letters of the standard U.S. English alphabet. This means that this method could receive 268, or approximately 200 billion possible strings as input. It is easy to see how testing every possible input value for an application is an impossible task.

It is equally obvious that such rigorous testing is unnecessary. In the preceding example, it is unlikely that any one string will produce errors that will not be produced by other strings. Thus, you can logically narrow down your input string to a few representative examples that test the method and provide assurance that the method functions properly. These examples are called test cases.

How you design your set of test cases is fundamental to your testing success. Too few test cases can lead to incomplete testing, which will likely allow errors to slip into your final product. On the other hand, too many test cases wastes time and money while yielding redundant results. You must decide on an appropriate test plan for your application with a goal of completeness and coverage of likely scenarios.

Designing Test Cases

As a minimal starting point when designing test cases, every line of code must be tested. Thus, if there are any decision structures in your method, you will need to define test cases that follow all possible branches of the code. Consider the following method:

Visual Basic .NET

Public Sub TestMethod(ByVal X As Boolean, ByVal Y As Boolean) If X = True Then MessageBox.Show("X is True") Else MessageBox.Show("X is False.") End If If Y = True Then MessageBox.Show("Y is True") Else MessageBox.Show("Y is False") End If End Sub

Visual C#

public void TestMethod(bool X, bool Y) { if (X == true) MessageBox.Show("X is true"); else MessageBox.Show("X is false"); if (Y == true) MessageBox.Show("Y is true"); else MessageBox.Show("Y is false"); }

The number of test cases needed to run every line of code in this method is two: one case where X and Y are true, and one case where X and Y are false. It soon becomes clear, however, that this approach is an inadequate test. Although every line of code is executed, no provisions are made for the variance of data. Depending on the values of the parameters provided to the method in the previous example, the method execution could take paths not covered by the test case for example, if X is true but Y is false, the method execution will follow a path that was not covered in the test plan. To test all possible paths in this method requires two additional test cases: one where X is true but Y is false, and one where X is false but Y is true. Therefore, at minimum your design for a unit test should include testing of all possible data paths.

Testing Data

Testing the functionality of all possible data points is a good plan, but to make your application robust, you also should test whether it can handle different kinds of data. You want your application to behave normally and give expected results when data within normal parameters is provided, and it should gracefully and appropriately handle data that is outside of the specified bounds as well. Thus, to be thorough, you must test your application with a variety of data inputs ranging from normal to extraordinary. Specific types of data conditions used to create test cases are described in the following sections.

Normal Data

It is important to test data that is within the normal bounds of program execution. Although it is usually impossible to test the entire range of normal data, your test cases should contain several examples of data that is normal for the program to process. This data should span the normal range of operation and should include the normal minimum and maximum values.

Boundary Conditions

Special consideration should be given to testing data on the boundaries of normal conditions. This includes the normal minimum and maximum values for program data, as well as values that are off by one. For example, to test the maximum boundary, you would include the maximum value, the maximum value minus one, and the maximum value plus one. This approach allows you to correct simple mistakes, such as using a > operator where a >= is required.

Bad Data

Using a variety of bad data in your test cases evaluates whether your program will crash in response to bad data or, worse, function normally and return inappropriate results. You should test values that are well outside of the normal scope of operation, including zero for non-zero values, negative numbers for positive data, and so on.

Data Combinations

Your test design should include a variety of combinations of the types of data previously mentioned. Errors might not be revealed until the correct data combination is used. For example, you might have a method that functions fine when each of its parameters is at its normal maximum, but fails when all of its parameters are at normal maximum. Similarly, combinations of known bad data can yield normal looking results. Consider the following method:

Visual Basic .NET

Public Function CalculateMySalary(ByVal Hours As Short, ByVal Weeks _ As Short) As Integer ' This method assumes a WageConstant that provides the hourly rate Dim mySalary As Integer mySalary = Hours * Weeks * WageConstant Return mySalary End Function

Visual C#

public int CalculateMySalary(short Hours, short Weeks) { // This method assumes a WageConstant that provides the hourly rate int mySalary; mySalary = Hours * Weeks * WageConstant; return mySalary; }

Given that a normal range for Hours might be 0 to 40, and a normal range for weeks might be 0 to 52, this method functions normally with nominal input. However, consider the following method call:

Visual Basic .NET

Dim Hooray As Integer Hooray = CalculateMySalary( 40, 52)

Visual C#

int Hooray; Hooray = CalculateMySalary( 40, 52);

A combination of bad data returns a seemingly normal result. For this reason, your test cases should test a variety of possible data combinations.

To create a unit test plan

  1. Begin by creating test cases that execute every line in the test unit.

  2. Add additional test cases until every possible path of data flow through the unit has been tested.

  3. Add further cases to test variance in the data the unit will process. In addition to testing nominal data, you should test boundary conditions, bad data, and different combinations of good and bad data.

  4. Determine the expected result of each test case in advance of the actual test.

  5. Execute the tests and compare observed results with expected results.

Lesson Summary

  • Unit testing using test cases is the process by which units of an application are tested to ensure that the units exhibit appropriate behavior during actual use. A test case is a set of run-time conditions that tests a given path and execution parameters.

  • Test cases should be designed to test a variety of conditions. At minimum, you should create test cases that test every possible data path through a unit. Your tests should include

    • Normal data

    • Boundary conditions

    • Bad data

    • Combinations of the preceding data conditions



MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[.  .. ]0-316
MCAD(s)MCSD Self-Paced Training Kit(c) Developing Windows-Based Applications With Microsoft Visual Basic. Net a[. .. ]0-316
ISBN: 735619263
EAN: N/A
Year: 2003
Pages: 110

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net