在前面一篇文章中,我们提到了如果进行接口测试,我们要素为url,访问方法,body,描述等等,当然针对某一个接口的数据返回,我们还需要做一些判定及存储的操作。因此,我们建立了一个apiDataBean的类来描述接口。
那么接下来,我们需要针对接口测试的环境做一些配置。这些配置是当前运行的所有接口所必须要进行配置的项,我们可以把这些个项目写在一个xml文件中,然后通过程序来读取。
例如:我们在做接口测试的时候可以进行以下这样的xml配置。
<?xml version="1.0" encoding="UTF-8"?> <root> <rootUrl>http://bx-test1.com:8006/IDAM2/CES_API/</rootUrl> <headers> <!-- 配置为自己的参数 --> <header name="Content-Type" value="application/json"></header> </headers> <params> <param name="cellcode" value="test001"></param> <param name="cellname" value="testname001"></param> <param name="PHBCODE" value="PHBCODE001"></param> </params> <project_name>API接口自动化测试报告</project_name> </root>
这里列了一个简单的例子来说明一下。首先,在接口测试中,我们一定会设置服务的主访问地址。其次,需要加入请求头的信息,针对某一个系统在做接口测试的时候,请求头信息大多是固定的。那么,我们这里可以把该系统中所有接口的请求头信息在配置文件中设定。关于这一点,框架后续会使用程序来实现。但是,针对个别的接口可能需要加一些特殊请求头的情况。(比如:需要加token认证才能访问),我们在之前设置apiDataBean的时候,预留了header的属性,可以利用这个属性来加入我们需要自定义header的部分。
接下来,在接口测试中,我们常常会用到一些参数,这些参数有些是url上在使用,有些可能是在body中使用。如果每一次都写实际值,不利于我们自动化用例的维护,我们也统一的写在配置文件中进行维护。当然,我们也可以在配置文件中写入更多的信息(比如:数据库的信息等),这里先不做展开,有兴趣的小伙伴可以自行扩展。
那么在准备好了当前接口测试所需要的参数后,我们需要一个配置类来读取这个xml文件,并输出对象到程序,以便程序调用。
接下来,我们一起看一下这个apiConfig的类:
package apiTest.apiConfig; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class apiConfigs {
//设定主要的三个属性,主机访问地址(字符串),header集合(Map),参数集合(Map) private String rootUrl; Map<String,String> headersMap = new HashMap<String,String>(); Map<String,String> paramsMap = new HashMap<String,String>(); public String getRootUrl() { return rootUrl; } public Map<String, String> getHeadersMap() { return headersMap; } public Map<String, String> getParamsMap() { return paramsMap; } //定义apiConfigs的实例获取方式 public apiConfigs(String configXmlPath) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(configXmlPath); Element rootElement = document.getRootElement();
//在rootUrl标签下获取主机访问地址 rootUrl = rootElement.element("rootUrl").getTextTrim();
//在headers标签下遍历header标签,然后将其存储到headersMap中 @SuppressWarnings("unchecked") List<Element> headerElements = rootElement.element("headers").elements("header"); headerElements.forEach((ele)->{ headersMap.put(ele.attributeValue("name").trim(),ele.attributeValue("value").trim()); });
//在params标签下遍历param标签,然后将其存储到paramsMap中 @SuppressWarnings("unchecked") List<Element> paramElements = rootElement.element("params").elements("param"); paramElements.forEach((ele)->{ paramsMap.put(ele.attributeValue("name").trim(), ele.attributeValue("value").trim()); }); //在projectName标签中获取项目名称,在log或报告中使用 Element project_name = rootElement.element("projectName"); if(project_name != null) { reportUtil.setReportName(projectEle.getTextTrim()); } } }
这样我们在进行接口测试的时候,可以将配置文件进行读取,然后对所有接口套用配置的参数。
另外,在实际的接口测试中,会遇到一些这样的问题:接口A的返回内容中,有些字段的值,是接口B请求时所需要使用的参数。
如果我们要访问接口B,就需要先将接口A中的这些字段存储出来,方便接口B来调用。
对于我们之前写的接口请求的构造类,并没有定义这个具体的变量。因为,第一,我们不知道要取什么值,需要定义多少个变量。第二,对于取值的类型,我们也无法确定。
那么,怎么处理这个过程中的参数呢?
如果使用过swagger的童鞋,肯定对{}里面加入变量名的方式比较熟悉。
在swagger中,使用{}加变量名的方式来定义需要录入的参数。我们可以借鉴这样一种思维,可以在我们的接口自动化程序中,先定义一个变量来存储接口A的返回内容,然后使用一种方式来对定义的变量进行读取。
但是,由于我们在接口测试中,有很多情况是需要传入json参数的,恰巧json的格式就是{}加上一些字符串内容,所以我们这里直接用{}来进行定义变量的转存不是很合适。
这里,我们定义一种方式来对过程参数进行存储并调用。
在这之前,我们需要再想一下,之前我们已经通过apiConfigs的类来读取了相应的参数。(确切的说是存在了一个Map中)我们将这个Map看成是一个公共参数池,使用${param_name}的方式来调用公共参数。
同理,我们也可以将过程参数存入公共参数池,把过程参数当成公共参数来使用。
那么怎么样才能调用公共参数池里面的参数呢?在这个之前,我们先回想一下正则表达式的相关使用。