java自动化-实际使用junit的演示
本文简单介绍一下我写的http接口后端框架
在经过之前多篇博客介绍之后,读者应掌握如下技能
1,自动运行一个或者多个junit框架编写的java代码
2,对数据驱动以及关键字驱动有一定的了解和认识,甚至可以编写简单代码
怎么说呢,在这个基础上,实际上对代码的能力就会有一定提升了,但是在实际应用中,会面对一大波问题,笔者也并不指望能把所有的坑都说一遍,本文来简单说一下接口和我的自动化后端逻辑
首先先说,各个大公司都有自己的各种方式的接口,分为提供给外部的接口和内部使用的rpc接口,这里不讨论rpc接口,而外部接口看,更多的恐怕是http接口和https接口,其中https接口,其本质就是http接口加密而成的,故本文,对http接口进行介绍
在之前的博客中曾经简单介绍过http请求,http分为多种请求方式,但是在实际应用中,post请求的连接https://www.cnblogs.com/xuezhezlr/p/7685750.html,get请求的连接https://www.cnblogs.com/xuezhezlr/p/7667995.html,在上文中可以看到,http请求一般的会包含两部分,一部分是请求的url,另一部分是请求的参数集合,所以可以像上面两个一样,使用doPost(String url, Map parameterMap)与doGet(String url,Map parameterMap)来执行http请求,在一些公司,同一个接口甚至使用get或者post,传输相同的参数也可以发送过去并请求成功
所以在代码中我们需要一大堆参数,和一个url,然后再进行断言和日志打印,先说说url,
一般的url,分为域名和接口,比如本文网址https://www.cnblogs.com/xuezhezlr/p/9129026.html,其中www.cnblogs.com是域名,而后面的xuezhezlr/p/9129026.html是一个接口名,一般的公司呢,至少分为2套环境,一套测试环境一套正式环境(有的公司还会有预发环境),有时候都是相同域名不同host,所以在接口测试中不同接口之间,后面的接口名往往不一样,而域名往往是一样的,转换域名的实质是,在测试环境执行代码还是在正式环境执行代码,所以在代码中有必要把url分为两部分,一部分在每一个接口class中写,而另一部分域名则应该在公共方法中声明,或者在一个文件中写
参数的话不用说了,可以参照之前的数据驱动博客
断言的话,主要是对返回值进行断言,一般的公司返回值,每个接口都会有一个code或者retcode等参数,标志该接口请求是否成功,如code=0000代表成功,0001代表参数不全,9999代表接口内部异常等等,这部分返回码个人认为应该在设计用例时候预期到,比如这一条用例返回成功,少传一个参数会返回失败,所以,完全可以在参数化的文档中进行声明,而另一方面,每个接口除了会返回一个统一的标志位之外,还会返回一大堆其他的如json等等格式的字符串,这部分的话也不是不能在excle中填写,但是成本很大而且,不具有普遍性,我一般都是在代码中来编写的而非excle
日志打印也很重要,在日志中要说明哪个接口哪一条用例执行成功或者失败,其实成功的话倒是无所谓,只需要最后能知道成功就行,失败的话需要在日志里面打印出来失败日志和返回值,以便在报告邮件中展示出来并让开发或者测试认识到,自动化测试最终结果,是说开发代码有变动导致接口异常呢,还是环境问题呢,还是测试代码问题?所以这部分也很重要,我是做在了excle或者数据库里面作为测试参数来看
下面是没有使用excle或者数据库等数据驱动的一个实例
@Test
public void testsSuccessgetcode() throws Exception{
applyParams.put(PbgDict.TYPE, "sendmessage");
applyParams.put(PbgDict.mobile, mobile);
get("/app/getcode",applyParams,"正常用例","0");
}public void get(String url,Map parameterMap,String a,String errno1) throws Exception {
System.out.println("==========get自动化测试" + url + a+"=========");
System.out.println("url:" + URI_BASE + url);
System.out.println("applyParams:" + parameterMap);
util.HttpUtil httpDoGet = new util.HttpUtil();
Map<String, Object> result = httpDoGet.doGet(URI_BASE + url, parameterMap);
System.out.println("result:" + result);
String errno = result.get(PbgDict.ERRNO).toString();
System.out.println("errno=" + errno);
System.out.println("------------------------------\n");
Assert.assertEquals(errno1, errno);
}
上文中,代码中一个接口只需要传输4个参数,一个是url,一个是参数,一个是描述,一个是返回码,代码中会封装get和post两种请求,然后url会和URI_BASE 这个域名变量拼接出来完整的url,而参数会用来传递,描述用来打印日志,返回码的预期用来和实际的返回码比较来做断言,这样在每个接口的断言以及日志处理上可以做到相同的处理方式
这时候我做的数据驱动是形如这样的excle
在上图中使用一个不同的sheet页来定义不同的接口,内容上第一列是预期返回码,第二列是描述,第三列以及后面的是传输的参数值
这样写出来的代码,复用性较低,基本上每个接口都要单独写一套传参的方式,主要因为每个接口,有不同数量的入参,也有不同名称的入参,比如这个接口传输a=1,下个接口恐怕就要穿b=2了,当然,还有一个问题是维护成本,接口的参数方式和数量变化时候,由于参数化对列敏感,所以要对代码进行统一修改
这时候我就在想,如何能够统一参数的数量和入参名称呢?在上上家公司,http请求大多是这样的参数形式,a=1&b=2&c=3这种,无论是get还是post,所以我看了http代码,
if(parameterMap.size()>0){
url_parameterMap = url +"?"+getMapString(parameterMap);
}
public String getMapString(Map parameterMap) throws Exception{
StringBuffer mapStr = new StringBuffer();
Set set = parameterMap.keySet();
Iterator it = set.iterator();
int len = set.size();
System.out.println(len);
int n =1;
while(it.hasNext()) {
if(n != len) {
String str = it.next().toString();
String str_value = parameterMap.get(str).toString();
String str_map = str + "=" +URLEncoder.encode(str_value,charset);
mapStr.append(str_map);
mapStr.append("&");
}
if(len == n){
String str = it.next().toString();
String str_value = parameterMap.get(str).toString();
String str_map = str + "=" +URLEncoder.encode(str_value,charset);
mapStr.append(str_map);
}
++n;
}
return mapStr.toString();
}
传进去的map最后还是会拼接成字符串,所以我不禁想,之前是map形式,我入参是多个,在get请求中我合并然后合而为一,如果说是我能在入参时候就合并为string的话,那么入参就是一个了,再把他们用来请求get,这样就能解决原有问题了
所以另一方面我又封装了一种get请求
public void get(String url,String parameterMap,String a,String errno1) throws Exception {
System.out.println("==========get自动化测试" + url + a+"=========");
System.out.println("URI:" + URI_BASE + url);
System.out.println("applyParams:" + parameterMap);
util.HttpUtil httpDoGet = new util.HttpUtil();
Map<String, Object> result = httpDoGet.doGet(URI_BASE + url, parameterMap);
System.out.println("result:" + result);
String errno = result.get(PbgDict.ERRNO).toString();
System.out.println("errno=" + errno);
System.out.println("------------------------------\n");
Assert.assertEquals(errno1, errno);
}
实质上就是doget的两个不同的方法,一个传2个string,一个传一个string和一个map
public Map<String,Object> doGet(String url,String parameterMap) throws Exception {
String url_parameterMap = url;
url_parameterMap=url +"?"+parameterMap;
System.out.println("url_Get:" + url_parameterMap);
URL localURL = new URL(url_parameterMap); URLConnection connection = openConnection(localURL);
HttpURLConnection httpURLConnection = (HttpURLConnection)connection; httpURLConnection.setRequestProperty("Accept-Charset", charset);
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
StringBuffer resultBuffer = new StringBuffer();
String tempLine = null;
if (httpURLConnection.getResponseCode() >= 300) {
throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
} try {
inputStream = httpURLConnection.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
reader = new BufferedReader(inputStreamReader); while ((tempLine = reader.readLine()) != null) {
resultBuffer.append(tempLine);
}
}
这样做的好处在于,可以把参数请求时候不使用map而使用string了,然后现在的接口代码是这样的
public class test_ylw_app_config_discovery extends PbgService {
Map<String, Object> applyParams = null;
private String miaoshu;
private String error;
private String value;
private static String key="/app/config/discovery";
@Parameterized.Parameters
@SuppressWarnings("unchecked")
public static Collection shiyan2() throws Exception {
File file = new File(postxlsapppath);
Object[][] object = getxlsData(file, 0, key);
return Arrays.asList(object);
}
public void initData() throws Exception { applyParams = new HashMap<String, Object>();
}
@Before
public void setUp() throws Exception {
initData();
}
@After
public void TearDown() throws Exception {
this.applyParams.clear();
this.applyParams = null;
}
@AfterClass
public static void delete() {
supdelete();
}
public test_ylw_app_config_discovery(String error, String miaoshu, String value){
this.error = error;
this.miaoshu = miaoshu;
this.value=value;
}
@Test
public void testdiscovery() throws Exception{
value= supinit.zhuanhua2(value);
post(key,value,miaoshu,error);
}
}
上述代码中,key是接口名,不同接口不一样,使用getxlsData方法读取指定excle中的指定sheet页key中的数据,然后再把参数部分合并,把excle原有的数据,分为3个参数,error,miaoshu和value,在每次执行的时候,由于是关键字驱动,使用supinit.zhuanhua2(value);来把value中的关键字转化为我们需要的数据再进行操作
从上文代码看到,在最后接口自动化的代码已经能做到,所有的都很相近,只有key不同,其他参数以及处理+断言基本一样有一些读者可能要问,key也可以进入excle1啊,,,其实我写的数据库版本的驱动就是把key写到了excle里面,最后针对不同的key进行断言,大多数接口的话除了对基本的返回码做一个校验之外还需要对其他的,如数据库等等进行校验,所以很难写到一起
总的来说,这就是我做的接口自动化了~~~感觉还很初级,需要提升啊,它对一个以http文明的小公司而言,已经是比较完整的了实际上
java自动化-实际使用junit的演示的更多相关文章
- java自动化-数据驱动juint演示,上篇
本文旨在帮助读者介绍,一般的全自动化代码接口,并简单介绍如何使用数据驱动来实现简单的自动化 在经过上述几个博客介绍后,相信读者对自动启动执行一个java编译过的class有了一定了解,也完全有能力去执 ...
- java.lang.ClassNotFoundException: org.junit.Assume$AssumptionViolatedException
java.lang.ClassNotFoundException: org.junit.Assume$AssumptionViolatedException 在spring框架中进行单元测试,出现标题 ...
- java 覆盖hashCode()深入探讨 代码演示样例
java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...
- JAVA简单Swing图形界面应用演示样例
JAVA简单Swing图形界面应用演示样例 package org.rui.hello; import javax.swing.JFrame; /** * 简单的swing窗体 * @author l ...
- java.lang.NoClassDefFoundError: org/junit/runner/manipulation/Filter
今天想写个随笔,最近经常遇到使用junit的时候报java.lang.NoClassDefFoundError,今天算是恍然大悟了,原来junit虽然在gradle里面配置了,也在Project an ...
- unit测试出现异常:Exception in thread "main" java.lang.NoSuchMethodError: org.junit.platform.commons.util
在进行单元测试时,测试出现异常 Exception in thread "main" java.lang.NoSuchMethodError: org.junit.platform ...
- java中如何使用Junit测试
java中如何使用Junit测试 一.总结 一句话总结:a.单元测试的测试代码在test文件夹下,和源码不在同一个文件夹下 b.测试的类方法都以test开头,后面接要测试的类或者方法的名字 1.JUn ...
- DotNet,PHP,Java的数据库连接代码大全(带演示代码)
C#数据库连接字符串 Web.config文件 <connectionStrings> <!--SQLServer数据库连接--> <add name="con ...
- Java笔记18:JUnit单元测试
1 从http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22junit%22%20AND%20a%3A%22junit%22 上下载最新的junit包. ...
随机推荐
- luogu P5302 [GXOI/GZOI2019]特技飞行
传送门 强行二合一可还行 首先\(c\)的贡献是不会变的,先考虑求出多少交点被矩形覆盖,交点的话可以按左端点纵坐标从下到上顺序枚举一条线段,然后维护右端点纵坐标的set,把之前处理过线段的右端点放进s ...
- 自编译Apache Spark2.3.3支持CDH5.16.1
1 下载源代码文件 https://archive.apache.org/dist/spark/spark-2.3.3/ 2 解压后导入编辑器,修改依赖的Hadoop版本,下面截图是修改后的,要看自己 ...
- linux oops调试
参考文章: arm 指令定位错误 https://blog.csdn.net/songcdut/article/details/41383483 linux mips指令学习 https://www. ...
- 将Chrome插件Momentum背景图片设为桌面壁纸
Momentum简介 Momentum插件是一款自动更换壁纸,自带时钟,任务日历和工作清单的chrome浏览器插件.官方的解释就是:替换你 Chrome 浏览器默认的“标签页”.里面的图片全部来自50 ...
- java -jar和hadoop jar的区别
hadoop jar可以看做是java -jar的升级,可以和它一样带参数,程序一样的解析 不同的是hadoop jar运行的jar包他会依赖于hadoop安装目录下面的一些环境,并且你jar包里指定 ...
- 命令行神器之argparse使用笔记
示例 废话不多说直接给例子: import argparse parser = argparse.ArgumentParser(description='Imbalanced Dataset Exam ...
- 51nod 2523
len=0 break len=1,f=0,ans++,保留前一行的v数组,即len不变:f=1,重新确定下一列中需要判哪一行(标记法),跟新v数组 这题思路很清晰,但是写代码的时候弄错好几个变量,列 ...
- 2018-2019-2 20165231《网络对抗技术》Exp0 Kali安装 Week1
下载Kali Linux系统 进入官网进入下载页面,因为我们是在虚拟机内使用,而官网已经为我们提供了VM版的所以我就直接下载了这个版本的. 根据官网提示使用管理员帐号root(密码为toor)登录,创 ...
- 关于VC预定义常量_WIN32,WIN32,_WIN64等预定义宏的介绍(整理、转载)
参考帖子: (1)MSDN上专门讲预定义宏:https://msdn.microsoft.com/en-us/library/b0084kay(v=vs.80).aspx (2)VS中属性页的配置介绍 ...
- xgb
xgb原理 xgb代码