Dealing with null Input/null ExpectedResults
处理输入为null/期望结果为null的情况
Problem
You want to verify the correct handling ofnull arguments passed to API methods under test.
问题
如何验证被测方法处理null参数是否正确?
Design
Use a special string token to representnull in your test case data file.Add logic to your test
harness that converts the null-token to anull input value.
设计
在测试用例中用特殊字符标记代表null,在我们的测试套件逻辑中加上将这个null标记转换为null输入值的代码。
解决方案
假设将原来的被测方法ArithmeticMean修改成考虑了输入为null的情况:
public static double ArithmeticMean(paramsint[]vals
{
if(vals==null)return 0.0;//modification
double sum=0.0;
foreach(int v in vals)
sum+=v;
return(double)(sum/vals.Length);
}//ArithmeticMean
然后我们可以在测试用例中加上null标记,如:
0001:ArithmeticMean:2 4 8:4.6667
0002:ArithmeticMean:NULL:0.0000
然后我们这样处理这个null标记:
string line,caseID,method;
string[]tokens,tempInput;
int[]input=null;
double expected,actual;
while((line=sr.ReadLine())!=null)
{
tokens=line.Split(':');
caseID=tokens[0];
method=tokens[1];
if(tokens[2]=="NULL")//null input
input=null;
else
{
tempInput=tokens[2].Split('');
input=new int[tempInput.Length];
for(int i=0;i<input.Length;++i)
input[i]=int.Parse(tempInput[i]);
}
expected=double.Parse(tokens[3]);
actual=MathLib.Methods.ArithmeticMean(input);
if(actual==expected)
Console.WriteLine(caseID+"Pass");
else
Console.WriteLine(caseID+"*FAIL*");
}//while
Comments
Testing API methods for null inputarguments is essential.Because we can’t store a null value
directly in the test case data,we use thestring token“NULL”.Using“NULL”is arbitrary but
makes the test case data and code morereadable than alternatives like“nil”or“invalid”.When
we read and parse a test case,we check forthe string“NULL”and then branch to special logic
in the test harness.The exact logic you usewill depend on the behavior of the method under
test.Notice that we assigned null to ourinput variable at declaration time:
int[]input=null;
and then reassign a null value if weread“NULL”from the test case file:
if(tokens[2]=="NULL")
input=null;
This is technically unnecessary but makesour code more readable and easier to modify.
Dealing with a null expected result usesthe same idea as dealing with a null input argument.
Suppose a new method namedHypergeometric()is added to the MathLib library under test,
and that the Hypergeometric()method returnsnull if all input arguments are 0.To test,we
store a string token such as“NULL”in thetest case file:
0001:Hypergeometric:0 0 0 0:NULL:
0002:Hypergeometric:1 3 5 7:2 4:
and then add logic to the test harness:
object expected=null;
while((line=sr.ReadLine())!=null)
{
if(tokens[3]=="NULL")
expected=null;
else
//parse tokens[3]into object expected here
//etc.
}
注解
用null值测试API方法是很重要的。由于在测试用例文件中我们不能直接存储null值,因此使用“NULL”标记,这个标记用的字符串是随意的,但是“NULL”字符串比其他的(nil,invalid)字符串使测试用例和代码的可读性更强。当我们在测试套件中读取和解析测试用例的时候,检查“NULL”字符串,并且建立逻辑分支。具体逻辑取决于测方法的行为。注意到,我们在声明input变量的时候就给它赋值null:
int[]input=null;
然后当从测试用例文件中读取到null的时候重新给它赋null值:
if(tokens[2]=="NULL")
input=null;
从技术上讲,这是不必要的,但是这样可使我们的代码更可读,并且更容易修改。处理预期结果为null的方式与处理输入为null的方式一样。假设我们在MathLib类中增加了一个新的被测方法Hypergeometric(),当所有传入的参数值为0的时候,该方法返回null。为了测试,我们在测试用例文件中存储了一个字符串标记,如“NULL“:
0001:Hypergeometric:0 0 0 0:NULL:
0002:Hypergeometric:1 3 5 7:2 4:
然后修改测试套件的逻辑:
object expected=null;
while((line=sr.ReadLine())!=null)
{
if(tokens[3]=="NULL")
expected=null;
else
//parse tokens[3]into object expected here
//etc.
}