Welcome to MSDN Blogs Sign in | Join | Help

Casting types and boundary testing

The traditional concept of boundary testing was established as a systematic procedure to more effectively and more efficiently identify a particular category of defects. Historically, boundary value analysis has focused on bounded physical (countable) linear input and/or output variables of independent parameters, and is especially useful in programming languages that are not strongly typed (such as C). The value of using the boundary value analysis technique is early identification of:

  • typographical errors of specific bounded values (especially artificial constraints on a data type)
  • improper use of relational operators around a physical bounded variable
  • errors in implicit or explicit casting between data types

The application of boundary value analysis is not easy, because identifying boundary conditions from the user interface is extremely difficult. Also, if the tester lacks an understanding of programming concepts such as data types, casting, and looping structures then identifying boundaries becomes a mysterious art rather than a professional practice.

Casting (or conversion) between data types occurs rather frequently in software. For example, a calculator may only accept integer values as inputs, but the output of a division operation may result in a decimal value. In this case the operands are converted or parsed from strings to integer values using int.Parse(operand), or Convert.ToInt32(operand) in C#. Now, in order for the division operation to display decimal values if the result is not a whole number the operands must be cast to doubles (or floats) as in the example below.

        private double DivideOperation(int operand1, int operand2)
        {
            //              the operands are explicitly cast from
            //              integer types to double types
            double result = (double)operand1 / (double)operand2;
            return result;
        }

OK...so that is the basics of casting types, now let's examine where casting can get us into trouble by exceeding physical bounded parameters. And to find these common errors we don't have to go too far. In fact, the Attributes feature of MSPaint program provides us with plenty of examples of boundary issues.

image

Notice the default units for Width and Height parameters is Pixels. Pixels are in hole numbers. The input parameters Width and Height will accept a decimal value; but if the units selected is Pixels the decimal will be rounded to the nearest integer value. However, selecting either the inches or centimeters radio buttons for Units will allow decimal inputs. This is a pretty good clue that there is some pretty serious casting of these input parameters going on below the GUI. Now, we should know that inches are larger than centimeters, and centimeters are larger than pixels in size. We should also know that the maximum allowable input in the width or height parameter is limited to 5 characters, or a maximum valid input boundary of 99999.

Now there is nothing particularly unique or interesting about 99999, but we know that Pixels defaults to integer values, and inches and centimeters use decimal values, and that inches is bigger than pixels. And now, the magic math. If 29875 inches = 75882.50 centimeters, then 29876 inches should equal 75885.04 centimeters. (It doesn't matter at this point if we click the OK button on the dialog and get an error message that reads "Please enter no more than 5 characters." even though we didn't enter those 8 characters the software did that all by itself. We might not like the fact the software does what it tells the user he/she specifically can't do, but (although many will argue this point) the program flooding its own edit control with more than 5 characters and then displaying an error message is really superficial and generally uninteresting.) But, it is a good thing we don't use the Attributes feature of MSPaint as a conversion calculator because when we select inches as the units and enter 29876 in either the width or height parameters, then select the Cm radio button the value converts to 0!

What is this magical math? How can this happen when we aren't even close to the maximum allowable input of 99999 inches? The value of 75885.04 is not some magical, unique or special value in computing. To understand what is happening we have to back up and convert from inches to pixels for a clearer picture. Select the inches radio button in the Unit groupbox, and enter the value 29875 for either the width or heigth parameters. Now select the Pixels radio button. Notice the value is 2147474. Now, testers know the upper physical bound of a signed 32-bit integer is 2 billion 147 million and some change (2,147,483,647 to be exact), but this value isn't close. But, what if the last 3 characters are truncated by the control? Even in that case 29875 * 71.882 (pixels/inch) = 2147474.75 and the most significant digits above 1000 is still a value below the range of a signed 32-bit integer value (-2,147,483,648 ~ +2,147,483,647). But, when we enter 29876 inches  and then select the pixels radio button the value jumps to 4294967 (which are the most significant digits above the one thousands place of an unsigned 32-bit integer value (0 ~ 4294967296). This is because 29876 * 71.882 (pixels/inch) =  2147546.632 (and again looking at the significant values above the one thousands place) exceeds the upper physical bound of a signed 32-bit integer (2,147,483,648) resulting in an implicit cast to an unsigned 32-bit integer.

Now, simply setting the Units radio button to inches, entering 99999 for either the width or height parameters, and then selecting the Cm radio button, or selecting the Pixel radio button and then back to inches or Cm would reveal an error. However, a professional tester has enough working knowledge of the underlying system (including basic programming concepts) to not only know how and in which situations this type of defect can occur, but they can also use their cognitive abilities (having a basis in or reducible to empirical factual knowledge [of basic programming concepts in this case]) to perform conscious intellectual acts (cognition) to analyze features and identify areas where this type of problem might occur, and can then apply logical and rational tests that have a greater probability of exposing a defect (if one exists), or providing other valuable information regarding the valid operation or correctness of that feature.

There are other bugs in this relatively simple feature regarding data types, and perhaps I shall expose those at a later time!

Published Wednesday, September 05, 2007 10:41 AM by I.M.Testy

Comments

# re: Casting types and boundary testing

Sorry, I drove off the rails when I saw "programming languages that are not strongly typed (such as C)."  C Language is strongly-typed of course.  I think the confusion has to do with the fact that C allows types to be implicitly determined (usually int) in the absence of explicit declaration.  That and the ability to cast a pointer to anything means you can (1) be confused and (2) create a lot of mischief.

The language is still strongly-typed, just not the way Java or C# are (where the ability to cast references is constrained and storage representation is not exposed).

Having gotten that off of my chest, I think the article is on point concerning boundary testing.  

My suspicion is that the "casting" in the MSPaint example is between strings and desired value format, although the model for fractional pixels (there are such things on some occasions).  The silent, over-generous acceptance of inputs raises a whole set of usability issues and design considerations.  I am not surprised that this is left to resolution by user trial-and-error discovery.  

Because it has become fodder for your example, I wager this MSPaint dialog interface is neither well-specified nor well-documented if it raises testing issues now.  It is not a programming-language problem as such.

Wednesday, September 05, 2007 2:19 PM by Dennis E. Hamilton

# re: Casting types and boundary testing

Hi Dennis,

Sorry, I struck a nerve. A strongly typed language is relative to what it is being compared. As you point out C is more strongly typed than some languages, but less than others.

I very much agree with your statement about design and usability issues and the "silent, over-generous acceptance of inputs." Over-generous allowance of inputs coupled with implicit casting is a classic example where boundary type defects can occur.

This bug is not caused by a flaw in the programming language per se, but a flaw in the design and implementation. The more a tester understands fundamental programming concepts (and the specifics of a particular programming language) the better he/she will be at identifying areas of high risk, and generating a rich set of tests that have a higher probability of exposing an error or demonstrating correctness and limit redundancy.

- Bj -

Wednesday, September 05, 2007 2:54 PM by I.M.Testy
Anonymous comments are disabled
 
Page view tracker