Unit Test for Buddi: Difference between revisions
No edit summary |
No edit summary |
||
Line 30: | Line 30: | ||
Once you think of something that could go wrong, write a test for it. Once that test passes, again ask yourself, "what else can go wrong?" and write another test, and so on. | Once you think of something that could go wrong, write a test for it. Once that test passes, again ask yourself, "what else can go wrong?" and write another test, and so on. | ||
=== Conformance === | |||
Many times you expect or produce data that must conform to some specific format. An e-mail address, for instance, isn't just a simple string. You expect that it must be of the form: | |||
* | |||
name@somewhere.com | |||
With the possibility of extra dotted parts: | |||
* | |||
firstname.lastname@subdomain.somewhere.com | |||
And even oddballs like this one: | |||
* | |||
firstname.lastname%somewhere@subdomain.somewhere.com | |||
Suppose you are writing a method that will extract the user's name from their e-mail address. You'll expect that the user's name is the portion before the "@" sign. What will your code do if there is no "@" sign? Will it work? Throw a runtime exception? Is this a boundary condition you need to consider?[1] | |||
Validating formatted string data such as e-mail addresses, phone numbers, account numbers, or file names is usually straightforward. But what about more complex structured data? Suppose you are reading some sort of report data that contains a header record linked to some number of data records, and finally to a trailer record. How many conditions might we have to test? | |||
* | |||
What if there's no header, just data and a trailer? | |||
* | |||
What if there's no data, just a header and trailer? | |||
* | |||
What if there's no trailer, just a header and data? | |||
* | |||
What if there's just a trailer? | |||
* | |||
What if there's just a header? | |||
* | |||
What if there's just data? | |||
Just as with the simpler e-mail address example, you have to consider what will happen if the data does not conform to the structure you think it should. | |||
And of course, if you are creating something like an e-mail address (possibly building it up from different sources) or the structured data above, you want to test your result to make sure it conforms. | |||
[1]E-mail addresses are actually very complicated. A close reading of RFC822 may surprise you. |
Revision as of 23:58, 19 October 2009
Unit Test for Buddi
CORRECT Boundary Conditions
Many bugs in code occur around "boundary conditions," that is, under conditions where the code's behavior may be different from the normal, day-to-day routine.
For instance, suppose you have a function that takes two integers:
public int calculate(int a, int b) { return a/(a+b); }
Most of the time, this code will return a number just as you expect. But if the sum of a and b happens to equal zero, you will get an ArithmeticException instead of a return value. That is a boundary condition—a place where things might suddenly go wrong, or at least behave differently from your expectations.
To help you think of tests for boundary conditions, we'll use the acronym CORRECT:
- Conformance — Does the value conform to an expected format?
- Ordering — Is the set of values ordered or unordered as appropriate?
- Range — Is the value within reasonable minimum and maximum values?
- Reference — Does the code reference anything external that isn't under direct control of the code itself?
- Existence — Does the value exist (e.g., is non-null, non-zero, present in a set, etc.)?
- Cardinality — Are there exactly enough values?
- Time (absolute and relative) — Is everything happening in order? At the right time? In time?
Let's look at each one of these in turn. Remember that for each of these areas, you want to consider data that is passed in as arguments to your method as well as internal data that you maintain inside your method and class.
The underlying question that you want to answer fully is:
What else can go wrong?
Once you think of something that could go wrong, write a test for it. Once that test passes, again ask yourself, "what else can go wrong?" and write another test, and so on.
Conformance
Many times you expect or produce data that must conform to some specific format. An e-mail address, for instance, isn't just a simple string. You expect that it must be of the form:
*
name@somewhere.com
With the possibility of extra dotted parts:
*
firstname.lastname@subdomain.somewhere.com
And even oddballs like this one:
*
firstname.lastname%somewhere@subdomain.somewhere.com
Suppose you are writing a method that will extract the user's name from their e-mail address. You'll expect that the user's name is the portion before the "@" sign. What will your code do if there is no "@" sign? Will it work? Throw a runtime exception? Is this a boundary condition you need to consider?[1]
Validating formatted string data such as e-mail addresses, phone numbers, account numbers, or file names is usually straightforward. But what about more complex structured data? Suppose you are reading some sort of report data that contains a header record linked to some number of data records, and finally to a trailer record. How many conditions might we have to test?
*
What if there's no header, just data and a trailer? *
What if there's no data, just a header and trailer? *
What if there's no trailer, just a header and data? *
What if there's just a trailer? *
What if there's just a header? *
What if there's just data?
Just as with the simpler e-mail address example, you have to consider what will happen if the data does not conform to the structure you think it should.
And of course, if you are creating something like an e-mail address (possibly building it up from different sources) or the structured data above, you want to test your result to make sure it conforms.
[1]E-mail addresses are actually very complicated. A close reading of RFC822 may surprise you.