net自动化测试之道API测试-确定测试结果

来源:互联网 发布:时光知味简介 编辑:程序博客网 时间:2024/04/29 13:43

Determining a Test Case Result

 

确定测试结果

Problem

You want to determine whether an API testcase passes or fails.

问题

如何确定我们的API测试用是通过了还是失败了呢?

Design

Call the method under test with the testcase input,fetch the return value,and compare the

actual result with the expected result readfrom the test case.

设计

调用被测方法,传入测试用例的输入,获取方法的返回值并与测试用例中描述的预期结果比较。

解决方案

string method,expected;

double actual=0.0;

if(method=="ArithmeticMean")

{

actual=MathLib.Methods.ArithmeticMean(input);

if(actual.ToString("F4")==expected)

Console.WriteLine("Pass");

else

Console.WriteLine("*FAIL*");

}

else

{

Console.WriteLine("Method notrecognized");

}

 

Comments

After reading data for a testcase,parsing that data,and converting the test case input to an

appropriate data type ifnecessary,you can call the method under test.For your harness to be able tocall the method under test,you must add a project reference to the DLL(in thisexam-

ple,MathLib)to the harness.The preceding code first checks to see which method the data will

be applied to.In a.NETenvironment,methods are either static or instance.ArithmeticMean()

is a static method,so it iscalled directly using its class context,passing in the integer array

input as the argument,andstoring the return result in the double variable actual.Next,the

return value obtained fromthe method call is compared with the expected return value(sup-

plied by the test casedata).Because the expected result is type string,but the actual result is

type double,you must convertone or the other.Here the actual result is converted to a string

with four decimal places tomatch the format of the expected result.If we had chosen to con-

vert the expected result totype double

 if(actual==double.Parse(expected))

Console.WriteLine("Pass");

else

Console.WriteLine("*FAIL*");

we would have ended up comparing two double values for exactequality,which is problematic

as types double and float are only approximations.As a general ruleof thumb,you should con-

vert the expected result from type string except when dealing withtype double or float as in

this example.

 注解

在读取了测试用例,分解,必要时转换类型后,我们可以调用被测方法了。为了能让我们的测试套件能够调用被测方法,我们必须添加被测方法所在DLL的引用(此例子中是MathLib)。在前面的代码中,我们首先确定数据应用到哪个方法。在.net环境中,方法要么是静态的,要么是实例的。ArithmeticMean()是一个静态方法,因此直接在类上调用,将整型数组input传给它,并且将返回结果存储在double变量actual中。然后方法返回值与预期返回值(由测试用例提供)比较。因为预期结果为字符串类型,但是实际结果是double类型的,我们必须作转换。在这里,我们将实际结果转化为字符串,“F4”表示保留4位小数。如果我们选择将预期结果转换为double的,可以这样:

if(actual==double.Parse(expected))

Console.WriteLine("Pass");

else

Console.WriteLine("*FAIL*");

结果我们以为对比的两个double值是完全相等,但问题是double和float类型只是约束,两个数比较几乎不可能相等。因此,这可以作为一般的经验,即像在此例子中一样,如果是处理double或者float类型时,不能将预期结果从string类型转换,其他情况下可以将预期结果由string类型转换为其他类型。

GeometricMean()is an instance method,so before calling it,you must instantiate a

MathLib.Methods object.Then you call GeometricMean()using its object context.If theactual

result equals the expected result,the testcase passes,and you print a pass message to console:

if(method=="GeometricMean")

{

MathLib.Methods m=newMathLib.Methods();

actual=m.GeometricMean(input);

if(actual.ToString("F4")==expected)

Console.WriteLine("Pass");

else

Console.WriteLine("*FAIL*");

}

You’ll usually want to add additionalinformation such as the test case ID to your output

statements,for example:

Console.WriteLine(caseID+"Pass");

For test cases that fail,you’ll often wantto print the actual and expected values to help

diagnose the failure,for example:

Console.WriteLine(caseID+"*FAIL*"+method+"actual="+

actual.ToString("F4")+"expected="+expected);

GeometricMean()是一个实例方法,因此在调用之前,我们必须实例化一个MathLib.Methods一个对象。然后通过这个实例化的对象调用GeometricMean()方法。如果实际结果与预期结果相等,测试用例就通过,我们在控制台打印通过的消息:

if(method=="GeometricMean")

{

MathLib.Methods m=new MathLib.Methods();

actual=m.GeometricMean(input);

if(actual.ToString("F4")==expected)

Console.WriteLine("Pass");

else

Console.WriteLine("*FAIL*");

}

通常,我们想加一些额外的信息在输出语句中,如测试用例ID:

Console.WriteLine(caseID+"Pass");

对于失败的测试用例,我们通常将实际结果和预期结果都输出来,这样方便分析。例如:

Console.WriteLine(caseID+"*FAIL*"+method+"actual="+actual.ToString("F4")+"expected="+expected);

A design question you must answer whenwriting API tests is how many methods will each

lightweight harness test?In manysituations,you’ll write a different test harness for every method

under test;however,you can also combinetesting multiple methods in a single harness.For

example,to test both the ArithmeticMean()and GeometricMean()methods,youcould combine

test case data into a single file:

当在编写API测试的时候,我们必须回答一个设计问题:每个轻量级套件将测试多少个方法?很多时候,我们为每个被测方法编写不同的测试套件,但是,我们也可以将多个方法的测试集中在一个测试套件中。例如,我们可以将测试ArithmeticMean()和GeometricMean()方法的测试用例写在一个文件中:

0001:ArithmeticMean:2 4 8:4.6667

0002:ArithmeticMean:1 5:3.0000

0004:GeometricMean:1 2 4 8 16 32:6.6569

0006:GeometricMean:2 4 8:4.0000

 

(The trailing blank space in“GeometricMean”is for readability only.)Then you can modify

the test harness logic to branch on thevalue for the method under test:

if(method=="ArithmeticMean")

{

//code to test ArithmeticMeanhere

}

elseif(method=="GeometricMean")

{

//code to test GeometricMeanhere

}

else

{

Console.WriteLine("Unknownmethod"");

}

The decision to combine testing multiplemethods in one harness usually depends on how

close the methods’signatures are to eachother.If the signatures are close as in this example

(both methods accept a variable number ofinteger arguments and return a double),then com-

bining their tests may save you time.Ifyour methods’signatures are very different,then you’ll

usually be better off writing separateharnesses.

(“GeometricMean”后面的空格仅仅是为了方便读)然后我们可以修改测试套件的逻辑:

if(method=="ArithmeticMean")

{

//code to test ArithmeticMean here

}

else if(method=="GeometricMean")

{

//code to test GeometricMean here

}

else

{

Console.WriteLine("Unknownmethod"");

}

通常是否将多个方法的测试写在一个测试套件中要看这些方法的签名有多接近。如果签名很接近,像本例中的那样(两个方法都接受若干个整型变量并且返回double的值),那么合并测试可能会节省我们的时间。如果签名非常不同,则分开写测试套件将会更好。

When testing an API method,you must takeinto account whether the method is stateless

or stateful.Most API methods arestateless,which means that each call is independent.Or put

another way,each call to a stateless methodwith a given input set will produce the same

result.Sometimes we say that a statelessmethod has no memory.On the other hand,some

methods are stateful,which means that thereturn result can vary.For example,suppose you

have a Fibonacci generatormethod that returns the sum of its two previous integer results.So

the first and second calls return 1,thethird call returns 2,the fourth call returns 3,the fifth call

returns 5,and so on.When testing a statefulmethod,you must make sure your test harness

logic prepares the method’s statecorrectly.

测试API方法时,我们必须考虑该方式无状态的还是有状态的。多数API方法是无状态的,这意味着每次调用都是独立的,或者换句话说,给定一些输入,调用无状态的方法将产生同样的输出结果。有时候,我们说无状态方法无记忆。另一方面,有些方法是有状态的,即这些方法的返回可以变化。例如,假设我们有个Fibonacci方法,它返回前两个整数之和,因此第一次调用和第二次调用返回1,第三次调用返回2,第四次调用返回3,第五次调用返回5……当测试有状态的方法时,我们必须确保我们的测试套件逻辑表达方法的状态是正确的。

Your test harness must be able to accessthe API methods under test.In most cases,you

should add a project reference to the DLLthat is housing the API methods.However,in some

situations,you may want to physically copythe code for the methods under test into your test

harness.This approach is necessary when testinga private helper method(assuming you do

not want to change the method’s accessmodifier from public to private).

我们的测试套件必须能够访问被测的API方法。在大多数情况下,我们应该添加包含API方法的DLL的引用。但是,有些情况下,我们可能想复制被测方法的代码到测试套件中。当测试私有的辅助性方法的时候,这很有必要(假设我们不想改变方法的访问限制)