GAT2.0使用文档(组合接口测试)
3.2接口用例场景组件
在此之前,大家应该都已经开发完成了一个最简单的接口测试用例,但是之前的接口用例的期望结果是固定值,不能动态的去做对比,有很大局限性。下面开始介绍怎样通过场景组件来动态对测试结果做断言。(以下步骤的前提是你已经完成了3.1小结中的简单测试用例。)
1) 单一接口用例的断言组件
l 第一步:在eclipse中导入IATStepGroup,根据你自己的接口功能模块添加新的package包.本例中我添加的package名字:cn.gateside.iat.steps.demo
l 第二步:在新建的package下添加场景组件类。类名称建议以接口的名称+Steps作为你的场景组件类名称。本例中我添加的场景组件类名称为:UserInfoSteps.java
l 第三步:添加好场景组件后,开始添加场景组件方法。在UserInfoSteps.类中添加如下代码:
@AssertStepMethodDesc(description=””,owner=””)
publicvoid asserUserInfo(String parameterID,String expectResut,String actualResult) throws Exception
{
InterfaceStepParameter parameter=(InterfaceStepParameter)ParameterHelper.getInterfaceStepParameter(parameterID);
JSONObject object=JSONObject.fromObject(actualResult);
MysqlDBOperationService service=new MysqlDBOperationService(parameter.ConnectiongString);
List<List<String>> resultSet= service.executeQuery(parameter.getValue(“announcerInfoSql”),parameter.getValue(“user”),parameter.getValue(“password”));
- assertEquals(object.keys(), resultSet.size()-1,”!!!the announcer number from interface is different from the number from database!!!”);
}
以上是一个最常用的断言场景组件的写法。接下来解释上述方法中的每一行。这里说到的每一行是指一行代码,请忽略换行,以及花括号。
H1:是断言方法的注解,包含两个参数description(方法功能描述),owner(方法的开发人员)
H2:场景组件方法定义,需要注意的是断言组件方法会有三个参数,分别表示这个方法中用到的数据的存储ID,期望结果,以及用例的实际结果。
H3:第三行是用来获取方法中用到的数据,根据parameterID从存储数据的xml文件中读取。此行可以照抄,如果没有用到数据可以不写此行。
H4:是将实际结果转换成Json对象,如果实际结果不是json字符串,请用相应的处理格式来处理。
H5,H6:两行是用来从数据库查询出期望的结果和实际结果做对比。对于H5行来说只有一个参数ConnectionString,在此是指JDBC链接字符串。H6行中三个参数,第一个只是要执行的sql语句,后面两个是访问数据库需要的用户名和密码。另外H6返回值是一个二维的list.resultSet.get(0)代表的是查询结果的column name.
H7:对实际结果以及查询到的期望结果做断言。
2) 断言场景组件的使用
完成自己的场景方法后,接下来介绍怎么使用。首先需要知道我们完成的场景方法的全名是什么。
l 场景方法全名:cn.gateside.iat.steps.demo.UserInfoSteps.asserUserInfo,也就是之前提到的pacakge.class.method
l 现在来看怎么使用我们的场景方法,先打开你在excel中创建的用例,将AssertType的值改为Custom.然后修改AssertMethod的值为cn.gateside.iat.steps.demo.UserInfoSteps.asserUserInfo:Test01
l 到这一步的时候,很多人可能不明白AssertMethod的值里面【:Test01】的意思,这一段表示这个场景方法用到的数据在xml中的存储ID.这个ID也就是在你开发场景方法的时候的第一个参数parameterID.
l 接下来看看,parameterID这个参数指定的数据是存放在哪里,对于Excel形式的用例,parameterID所指定的数据是存放在与Excel同名的xml文件里的。所以在我们示例中开发的场景方法用到的数据必须都放在xml中。
l 准备好数据后,就可以运行你的用例,注意如果只是修改了数据不需要重新执行GatCrteator.java生成用例。
3.3 多接口用例的开发
多接口组合的用例是一种更加普遍的试用场景,尤其是移动端的接口测试。因为移动端业务逻辑都在接口服务端实现,因此需要我们试用多个接口组合来完成一个业务逻辑的测试。接下来的我们来看看怎么样开发多接口组合的用例,在此假定你已经能够开发单一接口的用例,对框架的开发架构都已经熟悉。
1) 和单一接口用例的差别
存储形式:单一接口中,数据,用例都是存放在Excel文件中,一行为一个测试用例。多接口组合的用例,用例和数据分别单独存放在不同的xml文件里。
断言方式:单一接口的断言方式分为固定断言方式和自定义断言方式。固定断言方式包括相等断言和包含断言两种。自定义断言方式主要通过自己编写断言代码来完成。对于多接口组合用例来说断言方式都是自定义的,都需要自己开发代码来完成。
用例的组成:单一接口用例因为只有一个接口,因此只用Excel中的一行就能代表一个用例。对于多接口组合的用例来说,每一个用例都是由多个步骤组合而成,也就是说由多个Step方法组合完成。
2) 和单一接口用例的共同点:
用例数据:用例数据都是存放在xml中,而且存放数据的规则,xml格式,xml中标签的含义都是完全一致的。
用例的生成:都已通过执行GatCreator.java来完成。
3) 多接口用例的组成部分
用例描述文件:用例描述文件是一个以TestCase.xml结尾的xml文件,注意一定要以TestCase.xml结尾,这是多接口组合用例的标示,否则在执行GatCreator.java的时候将不能生成用例。下图就是一个示例性的用例描述文件。
一个用例描述文件,也就是一个TestCase.xml文件可以包含很多个测试用例,不再像单一接口用例限定一个excel sheet只能编写一个接口的用例。接下来我们解释一下用例描述文件中的标签。
l <AllTestCases></AllTestCases>:每一个用例描述文件有且仅有一个这样的标签,用例相关的信息都要放在这个标签内。
l <StepParametersFilePath></StepParametersFilePath>:上图中第一个红框内的标签,这个标签中的内容:标示的是组成用例的每一个Step方法使用的数据存放在哪个文件中。这个标签是对用例描述文件中Step方法数据存放文件的全局描述。另外这个标签也可以做为TestCase,Step等标签的属性来为单个TestCase或者单个Step定义自己专属的配置。在Step,TestCase都有这个属性的情况下,框架读取配置的优先级是Step的配置优先于TestCase,TestCase优先于全局配置,对于其他全局配置而言,这个优先级同样适用。对于全局配置标签而言,一个文件只能有一个。
l <StepAssembly></StepAssembly>:上图红框中的第二个标签。这个标签也是一个全局配置标签。表示在这个用例描述文件里,所有用到的Step方法都在这个包里。这个全局配置也可以作为TestCase,Step的属性。注意这个标签的值最后的小点别忘记了。
l <StepGroup></StepGroup>:上图红框中第三个标签。这个标签同样是一个全局配置标签。虽然叫StepGroup,其实代表的是在这个用例描述文件中,所有用到的Step方法都在这个类中。这个全局配置也可以作为TestCase,Step的属性。
l <TestCase></TestCase>:上图红框中第四个标签.这个标签代表了一个用例。ID属性是他的唯一标示,因此不能重复,Name属性同样不能重复。它还有Step子标签,我们前面说过了,一个用例是多个Step组成的,因此一个用例可以有多个Step标签。
l <Step></Step>:这个标签代表了一个用例的一个步骤。StepName:属性是一个StepMethod的名称,StepParameterID是这个StepMethod用到的数据在全局配置中提到的文件中的ID标示。当然如果你自己为Step设置了StepParametersFilePath这个属性,那么这个ID就是你自己设置的这个文件中的ID了。
l 最后总结一下:多接口用例是由多个自定义的方法组成,这个用例由那些方法组成,以及用到了那些数据这些信息最后会存放在一个用例描述文件中。当你编辑完一个用例描述文件后,你就可以使用GatCreator来生成具体的代码了。
数据文件:也就是Parameter.xml文件这个文件要和TestCase.xml文件一样都放在开发架构中的DataFiles\Xmls文件夹下。文件的具体结构和单一接口中的Parameters.xml文件一致。在这里就不多说了。
代码的写法:
public class DemoStep
{
@StepMethodDesc(description=””,owner=”tiande.zhang”)
public void Step1(String parameterID) throws Exception
{
InterfaceStepParameter parameter=(InterfaceStepParameter)ParameterHelper.getInterfaceStepParameter(parameterID);
WebConversation currentConversation=HttpUnitHelper.createConversation();
WebRequest currentRequest=HttpUnitHelper.createWebRequest(parameter.getValue(“url”),parameter.getValue(“httpmethod”));
HashMap<String, String> urlParameters=parameter.getURLParametersMap();
if(urlParameters.size()!=0)
{
HttpUnitHelper.setParameters(currentRequest,urlParameters);
}
WebResponse response=currentConversation.getResponse(currentRequest);
System.out.println(response.getText());
StepValuePool.createInstance().getValueDic().put(“doubiToken”,response.getText());
}
@StepMethodDesc(description=””,owner=”tiande.zhang”)
public void Step2(String parameterID) throws Exception
{
System.out.println(parameterID+StepValuePool.createInstance().getValueDic().get(“doubiToken”).toString());
}
@AssertStepMethodDesc(description=””,owner=”tiande.zhang”)
public void Step3(String parameterID,String expectResut,String actualResult)
{
SimpleLogger.logInfo(this.getClass(),actualResult);
}
l 代码的整体写法和为单一接口写断言方法是一致的,都是写在IATStepGroup中。
l Step方法都是无返回值的,而且只接受一个参数那就是parameterID.切记只有一个String型的参数,参数个数类型都不能随意别更,否则会出错。
l 所有Step方法,断言方法都要加相应的注解,否则可能服务被调用。切记
l 总结:以上部分就是在业务无关的情况下,代码部分我们要注意的地方。
4)多接口组合用例用到的类,方法
在我们做多接口组合的用例的时候,搜索的事情都需要我们自己写代码完成。包括发送http请求,设置http请求参数,解析对比返回值等等。为了方便大家,框架本身提供了大部分的帮助类来帮助大家完成工作。当然你也可以自己写这些类来完成工作。
(1)获取参数等数据
InterfaceStepParameter parameter=(InterfaceStepParameter)ParameterHelper.getInterfaceStepParameter(parameterID);
使用这句话就能根据parameterID获取到我们需要的数据。那我们来看看InterfaceStepParameter这个类有哪些属性和方法。
类名称:InterfaceStepParameter
方法/属性名称 | 返回值 | 功能用途 | 备注 |
getURLParametersMap() | HashMap<String,String> | 返回用于URL传递的参数键值对 | 在parameters.xml中存储的键值对的Key值的第一个字符为$时该参数将被认为是URL参数 |
getValue(String key) | String | 使用Key返回存储的value | |
updateParameters(String key,String value) | void | 使用Key,value更新或添加已有数据 | 该方法不会修改xml中的数据,只会修改当前内存中的数据 |
parameter.updateURLParameters(key, value); | void | 使用键值对更新已有的URL参数值 | 该方法同样不会更新xml中数据,仅是更新内存中的数据 |
CommandText | String | 对应这你在parameter.xml中的CommandText值 | 可以为空 |
ConnectionString | String | 对应这你在parameter.xml中的ConnectionString值 | |
ID | String | parameterID | |
Name | String | parameterName |
(2) 发送请求
WebConversation currentConversation=HttpUnitHelper.createConversation();
WebRequest currentRequest=HttpUnitHelper.createWebRequest(parameter.getValue(“url”),parameter.getValue(“httpmethod”));
HashMap<String, String> urlParameters=parameter.getURLParametersMap();
if(urlParameters.size()!=0)
{
- setParameters(currentRequest,urlParameters);
}
WebResponse response=currentConversation.getResponse(currentRequest);
- out.println(response.getText());
类名称WebConversation :httpunit的类使用即可,在此不多说
类名称WebResponse:用于获取请求返回值的类。此类为httpunit的类,使用即可。有兴趣可以通过互联网了解
类名称HttpUnitHelper
方法/属性名称 | 返回值 | 功能用途 | 备注 |
createConversation() | WebConversation | 使用单例模式创建WebConversation | |
cleanConversation() | void | 将之前创建的WebConversation清空,下次创建之前将会重新创建 | |
createWebRequest(String httpurl,String httpMethod) | WebRequest | 创建WebRequest对象 | |
setParameters(WebRequest currentRequest,HashMap<String,String> urlParameters) | void | 将需要通过HttpUrl传递的参数与url做绑定 |
(3)在StepMethod传递数据
由于我们的每个StepMethod都是相互独立的。因此怎样将Step1的结果数据传递给Step2作为输入参数就成了问题。
StepValueHelper.putStepOutputValue(“key”,”value”);
- getStepOutputValue(“key”);
类名称:StepValueHelper
方法/属性名称 | 返回值 | 功能用途 | 备注 |
putStepOutputValue(String key,Object value) | void | 将要传递的值以键值对的形式存放在内存中 | Key必须全局唯一 |
getStepOutputValue(String key) | Object | 从内存中根据key读取value |
(4) 由于我们还需要动态的获取数据库中的数据作为我们的期望结果,因此还提供了数据库查新帮助类。
MysqlDBOperationServicemysqlservice=new MysqlDBOperationService(conectionstring);
List<List<String>> resultList= mysqlservice.executeQuery(commandtext,username,password);
方法/属性名称 | 返回值 | 功能用途 | 备注 |
MysqlDBOperationService(String connectionstring) | 构造函数 | 仅提供了mysql数据库的访问helper,其他类型的数据库可以根据需要自己编写 | |
executeQuery(String commandtext,String username,String password) | List<List<String>> | 根据sql语句,用户名,密码返回查询结果 | List[0]获取到的第一个list中包含返回值的列名称 |
executeNoneQuery(String commandtext,String username,String password) | void | 执行sql语句不返回任何值 |
(5) 将返回的json字符串转化为json对象
JSONObject resultObject=JSONObject.FromObject(jsonString);
用于将json字符串转化为json对象的方法很多,大家在使用过程中可以自己自由选择。
(6) 断言方法
框架中使用的断言方法使用的是Testng本身的断言类和方法,在此不作过多说明。具体怎么使用请自行搜索学习。除了Testng的断言类和方法你也可以使用你知道的其他断言类和方法,当然也包括你们自己写的。
3.4 接口用例开发总结
看到这里,接口用例的开发就基本结束了,对于单接口用例的开发来说相对简单一些,可定制程度,应用场景也要简单一些。我们在日常的测试过程中,更多的可能是使用多接口组合的方式开发用例。对于多接口组合的用例来说,框架提供了帮助类,不再对接口测试的具体逻辑,业务做限制,给了大家足够的自由度来测试你的接口。自由度的提升也就意味着大部分的工作需要靠大家自己来开发代码完成。接口用例的开发文档就暂时写到这里。后续还有继续写怎么用GAT来开发Web自动化用例等等。可以事先透露一些,如果你学会了怎么去做多接口组合的用例,那么使用框架怎么学Web自动化用例你已经会了一大半。