java脚本接口自动化测试_接口自动化测试实践的记录
接口测试实践的记录
在敏捷开发交付的流程中,自动化测试实际上被放在一个看起来挺重要的位置,而自动化测试中,接口测试是一个投入产出比比较高的
一种自动化测试的形式,而我自己也做了一个这样的脚手架一样的东西可以方便进行自动化测试,关键是在一些现有第三包的基础上做实现,其实一个脚手架不需要几个 JAVA 类就可以完成了,至少我自己的这个在 10 个文件以内.要论行数估计也没有多少代码量,主要时间其实都是在想怎么更方便的写自动化测试,怎么使用以后的开源代码了。
下面介绍一下我自己如何完成这个自动化接口测试
脚手架设计和实现的,以及我自己实现过程中的种种发现。主要从以下几个方面来讲:
如何构建接口自动化测试的脚手架
关于接口测试参考的一些资源
关于接口测试的后续的一些想法
如何构建接口自动化测试的脚手架
接口测试本文中主要是指 HTTP 的请求,构建接口自动化测试脚手架的时候,首先先看看平常接口测试,测试人员时如何做的,我了解主要是以下几种方式:
通过操作页面/APP 来触发接口调用
使用诸如 SOAPYUI/JMETER/POSTMAN 或者其他的客户端工具来进行接口测试
我自己都使用过 SOAPUI/JMETER/POSTMAN,不能说使用的多么深入,但是常用的功能也都有用过,比如 SOAPUI 构建一个项目完整的接口自动化测试用例,大概有 200+ 以上的用例,可以支持不同的测试环境,检查点中可以检查数据库,使用 XPATH/XQUERY 来检查/获取指定的值,进行不同 API 的数据传递等等,这些工具 (指功能测试方面) 大体的逻辑我觉得是类似的,基本上都有:
发起请求的客户端,需要测试人员构建,也有通过 WSDL/WADL 自己生成的,不过数据都是需要测试人员输入的
根据表达式进行取值的 Resolver,就是可以根据 XPATH/XQUERY 语法,或者其他的语法来获取指定的值,
就是用来传递上下文数据的一种方式
外部可以参数话数据,比如环境配置
可以查看测试结果,这个其实可以理解为某种测试框架的一个功能,比如 JUNIT,TESTNG
接口自动化测试脚手架的构建
根据以上的分析如果自己需要实现的话,最主要需要实现一下其实就是请求的构建,请求构建包括了:
发起请求的客户端
请求数据的构建
对于发起请求的客户端就直接使用了 Spring RestTemplate,考虑的主要原因如下:
使用相对比较方便,模块化比较清晰
可以使用 HTTPClient 的实现
Spring RestTemplate 所在的包还有其他一些接口的支持,以后如果使用其他接口可以不需要换包也可以做
在实际的使用过程中,其实也遇到了一些问题,比如如下的内容:
HTTPS 的访问
开发接口定义不够准确的问题,造成使用 RestTemplate 时候出现了一些不在开始预期范中的问题
如何解决这些问题,在后面再详细介绍,这里说明一下使用 RestTemplate 的一个主要流程:
1. 构建请求,设置请求的 Header,URL,Accept,ContextType,Token 等等
2. 调用请求获取返回的 Response,
这个 ResponseRestTemplate 中实际上封装了一个 ResponseEntity 的类,里面包括了请求状态,Body 之类
RestTemplate 有个好处就是如果给 RestTemplate 设定了 MessageConverter 的话,他可以自动把请求的返回类型直接转换,比如你发起请求的时候设置了 JOSN 的 Message Converter,他可以帮你把类,或者字符串自己转化为 JSON 来发送,同样如果是返回值是 JSON 的话,也可以帮你自己将 JSON 转换成你指定类型的 JAVA BEAN
说完这个流程,我们就说说如何通过 RestTemplate 构建一个简单的 HTTP 请求:
Map urlVariable = new Map ();
urlVariable.put("q","test");
JavaBean javaBean = restTemplate.getForObject("http://www.baidu.com",JavaBean.class,urlVariable);
JavaBean javaBean1 = restTemplate.postForObject("http://www.baidu.com",JavaBean.class,urlVariable);
ResponseEntity e = restTemplate.getForEntity("http://www.baidu.com",JavaBean.class,urlVariable);
实际上使用 RestTemplate 还是挺简单的,不过为了让使测试更为方便一点,然后每个人的代码更统一点,自己重新封装了一下 RestTemplate 的使用,主要分为三个概念:
Service 的描述
测试数据
客户端调用
接口服务描述
Service 的描述实际上就是一个 JSON 文件,只不过自己规定了一下,格式类似于,这个文件描述了 API 的定义,当然 API 的 body 没有在这个里面,不过为了不把事情搞复杂,就暂时不放在这个里面.
{
"apiDomainName": "applicationName",
"contentType": "application/x-www-form-urlencoded",
"headers": {
"Accept": "application/json, text/javascript, */*"
},
"method": "POST",
"pathParameters": [],
"queryParameters": [
"username",
],
"resourceURL": "/application/subdomain"
}
测试数据类:
private Map queryParameters = Maps.newHashMap();
private Map pathParameters = Maps.newHashMap();
private Map headers = Maps.newHashMap();
private T body;
而如何调用客户端就变成,而且其实每一个 API 的访问其实都可以这样子来做,
ResponseEntity response = RestTemplateHelper.build(serviceDescriptionPath,requestData).call();
说明一下的是:
serviceDescriptionPath 就是接口的描述
requestData 就是需要进行测试的数据
然后实际上接口的描述是开发还没有开发好的时候就已经定了的,所以这里的变量就变成如何构建 requestData 了
构建 RequestData
构建 requestData 实际上就是设计测试用例,那么这里也是使用 Excel 的方式,将不同的值填写到 excel 里面,不过为了减少 set 值这样的操作,这个脚手架就提供了一些工具,可以直接将数据设置到 RequestData 实例,具体的操作如下:
Excel 是如下格式的:
变量名
测试用例 1
测试用例 2
data.queryParameters(username)
1
1
data.queryParameters(year)
2015
2014
data.queryParameters(month)
10
11
说明一下,通过反射的方式,可以直接生成一个 requestData 的实例,同时 queryParameters 中值已经设置好了,这样调用代码中就不需要写类似于:
RequestData data = new RequestData();
data.queryParameters.put("username","1");
data.queryParameters.put("year","2015");
这里有兴趣的同学可以参考这个包:里面其实已经有很方便的通过反射去赋值了,
org.jodd
jodd-bean
3.6.6
使用 TestNG 的 DataProvider
刚才讲述了如何发生生成数据,那么通过 Excel 的方式提供不同的数据,就可以通过 TestNG 的 DataProvider 了
所以测试数据通过,TestNG data provider 的实现在这里就不多少了,网上其实有很多内容了.
接口测试的代码看起来就是这个样子了 @DataProvider(name = "data")
public Iterator getAPITestData(Method m) throws Exception {
Map clazz = new HashMap();
clazz.put("RequestData", RequestData.class);
Iterator y = TestData.provider("testcase/api1.xls", m, clazzMap);
return y;
}
@Test(dataProvider = "data")
public void testAPITest(RequestData data) {
ResponseEntity response = RestTemplateHelper.build(serviceDescriptionPath,requestData).call();
Assert.assertEqual(response.getStatus,200); // response 的期望值实际可以通过dataprovider传入
}
而且几乎所有的代码都差不多成这个样子了,那么获取可以写个代码生成的东西,当然最后通过了 JsonPath 写了一些获取 JSON 值的工具,这个暂时也就不说了.
那么代码生成吧
当封装好这些东西之后,发现所有的接口都类似了,然后就做了代码生成的工具了,代码生成器的入口实际上个就是那个服务描述文件开始的,
所以代码生成器的参数就是服务描述文件,在实际的使用的过程中,接口描述这个文件也可以自动生成,目前总共支持以下几种:
手动编写描述文件
抓取开发 API 规格网站接口的描述,自动生成描述文件
解析 HAR 文件自动生成描述文件,解析 HAR 其实不难,就是繁琐一点字段有点多
后续想打通和 POSTMAN 的连接,可以接收 POSTMAN 的导出文件,然后也可以导出 POSTMANT 的,以后开 BUG 就什么也不说,直接放一个 POSTMAN 文件其实也挺帅的
至此一个接口测试的脚手架就大致完成了.总结起来就是:
封装了 RestTemplate,让他接受一个接口的描述文件,一个请求的数据
通过 Excel 传数据给请求的数据进行数据驱动
相同类似的代码进行代码生成
最后其实这样子使用下来,接口构建几个简单一点的自动化测试用例,其实也就是几分钟的事情.
一些细节
在实现过程中,实际上还有一些特殊情况,比如说需要 token,认证信息,这些通过一个公用函数的方式就可以解决,然后在代码生成的时候
直接讲这个放在实际测试的接口前面调用. 后有就是上面说到的的:
HTTPS 的访问
开发接口定义不够准确的问题,造成使用 RestTemplate 时候出现了一些不在开始预期范中的问题
HTTPS 的访问是通过如下代码解决的,创建一个略 SSL 的 httpclient 就可以了
public static RestTemplateClientHelper getHttpClientImplInstance(){
RestTemplateClientHelper client = new RestTemplateClientHelper();
HttpClient httpClient = getIgnoreSSLHttpClient();
client.setTemplate(new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)));
return client;
}
/**
* 获取忽略SSL的httpclient,支持https的请求
* @return
*/
private static HttpClient getIgnoreSSLHttpClient() {
CloseableHttpClient httpClient = null;
try {
httpClient = HttpClients.custom().
setHostnameVerifier(new AllowAllHostnameVerifier()).
setSslcontext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build()).build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
logger.error(e);
}
return httpClient;
}
还有一个就是有时开发的接口返回类型 (accept type) 不能让 RestTemplate 处理,那么其实添加自己定义个 MessageConverter 就好了:
下面是一个修改阿里自己的 FastJSON 的 MessageConverter 的例子,
其实也没改什么,就是捕捉了一个异常,主要是不知道什么原因调用时候 readInternal 就抛出和编码格式有关系的异常,然后就捕捉了一下异常反正也就把那个问题就没有了,不过这个改法应该也是有问题的.
public class ModifiedFastJsonHttpMessageConverter extends AbstractHttpMessageConverter {
........
public ModifiedFastJsonHttpMessageConverter() {
super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8));
this.charset = UTF8;
this.features = new SerializerFeature[0];
}
............
protected Object readInternal(Class> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream in = inputMessage.getBody();
byte[] buf = new byte[1024];
while(true) {
int bytes = in.read(buf);
if(bytes == -1) {
byte[] bytes1 = baos.toByteArray();
try {
return JSON.parseObject(bytes1, 0, bytes1.length, this.charset.newDecoder(), clazz);
}catch (Exception e){
return baos.toString("UTF-8");
}
}
if(bytes > 0) {
baos.write(buf, 0, bytes);
}
}
}
........
}
后续的一些想法
后续希望在这个基础上再做点其他的一些事情:
增加 POSTMAN 的代码生成的支持
探索能不能通过 API 接口描述直接生成 JMETER 的 JMX 文件,可以讲基础的 JMETER 性能测试的基础代码也生成好
整理一下放到 GITHUB 上面,其实整个脚手架自己也就是几个文件而已,:)
建立一个 MOCK SERVER,方便模拟一些 API 调用的方式
做一个简单点获取 JSON 中指定字段,然后传递给下一个 API 使用的工具
一些资源
java脚本接口自动化测试_接口自动化测试实践的记录相关推荐
- java 接口继承_接口是否可继承接口(java)
展开全部 Java语法中,接口32313133353236313431303231363533e59b9ee7ad9431333366303839可以继承接口,抽象类可以实现接口,抽象类可以继承实体类 ...
- api接口加密_接口加密如何测试?
摘要算法: 对明文编码生成信息摘要,以防止被篡改.比如MD5使用的是Hash算法,无论多长的输入,MD5都会输出长度为128bits的一个串. 摘要算法不要秘钥,客户端和服务端采用相同的摘要算法即可针 ...
- 学科实践活动感悟50字_初中学科实践活动记录50字3篇
初中学科实践活动记录 50 字 3 篇 现代社会中很多都是三口之家,在这里,我们其实不难 发现实在大多数养尊处优的不是父母,而是我们.初中学科 实践活动记录 50 字 1 人们都说:劳动最光荣. 这一 ...
- java接口测试框架搭建_接口自动化测试框架搭建
一.原理及特点 参数放在XML文件中进行管理 用httpClient简单封装一个httpUtils工具类 测试用例管理使用了testNg管理,使用了TestNG参数化测试,通过xml文件来执行case ...
- java接口自动化_接口自动化实现
一.实现框架: java+maven+testng+reportNG+jenkins框架 二.框架原理: 使用脚本发送HTTP请求返回接口的响应结果,并将代码存放在svn,Git中,jenkins可以 ...
- python自动化测试脚本怎么编写_编写自动化测试脚本心得---菜鸟入门篇
编写自动化测试脚本心得 -------- 菜鸟入门篇 本文中将不会讲解 ISEE 的测试原理.不说明 Python 的常用语法.不介绍 OTP 测试平 台的架构, 自动化测试组的牛人们已经为我们编写了 ...
- Java声明定义抽象类_接口_继承_实现
文章目录 声明定义抽象类 声明定义接口 派生类.抽象类.接口的继承要点 声明定义抽象类 public abstract class CRMSystem {public abstract Client ...
- jenkins构建后脚本不执行_接口管理工具ApiPost-预(后)执行脚本常用方法集合
本文主要讲解接口管理工具ApiPost的预执行脚本和后执行脚本里,常见的响应参数变量和常用方法集合. ApiPost简介: ApiPost是一个支持团队协作,并可直接生成文档的API调试.管理工具.它 ...
- java自动输入验证码_【自动化测试】使用Java+selenium填写验证码成功登录
这是我第一次发博客,若有问题,请多多指教! 本次是为了帮忙解决,如果在平时自动化遇到有验证码填写的情况,我们如何成功登录情况. 思路: 首先我们先将验证码复制并保存成一个图片,然后使用tesserac ...
最新文章
- 无论是舆论风波,还是实力较量,BCH从来就没有怕过
- PaddlePaddle yolov3
- Delphi中DLL封装业务逻辑的实现
- 输入一个正整数n,计算s=1-1/3+1/5-1/7…前n项之和
- 解决pycharm中新建的工程因为运行图标等均为灰色而无法运行的问题
- ansible+Jenkins+supervisor(Jenkins守护进程)
- 老员工恳请加薪,老板“不愿意做就辞职”
- 欧几里得算法及扩展欧几里得算法简单解释
- centos6.5 mysql登陆_centos6.5下mysql无法登陆的问题
- 微服务学习之02支付模块构建(单个、集群)【Hoxton.SR1版】
- 为什么定积分可以求面积?
- 一张图解释DNS域名服务器的作用
- filebeat7.7.0相关详细配置预览- Setup ILM
- 微信公众平台教程--素材编辑
- 计算机音乐数字乐谱生僻字,《生僻字》歌曲简谱
- 【车载开发系列】UDS诊断---OBD基础概述
- 树莓派配置红外遥控及关联python程序
- 华为HCNP h12-221习题训练加解析(1-13)
- Oralce数据库的详解解析(包括操作步骤)【1】
- Oracle VM VirtualBox安装Win10系统
热门文章
- Mendix将升级低代码软件开发平台,发布全新数字化生态系统、行业云
- 字节大战腾讯元宇宙;Docker 自己定制镜像;VMware 云桌面助力秦皇岛市第一医院;微软开源 Cloud Katana;...
- 赠书 | IoT 的真正目标是什么
- DevOps:从「蒸汽时代」到「高铁时代」,SUNMI DevOps转型之路 | 原力计划
- 图解 Python 算法
- 华为愿出售5G技术渴望对手;苹果将向印度投资10亿美元;华为全联接大会首发计算战略;腾讯自研轻量级物联网操作系统正式开源……...
- 容器精华问答 | 我们为什么需要容器?
- 微服务与单体架构:IT变革中企业及个体如何自处?
- linux烧录文件的格式,制作emmc 烧录文件
- Centos7 安装Go环境