服务端的测试,大多数内容都围绕着接口展开。对于接口测试,无非也是功能、自动化、性能测试为主,偶然想到一个问题,如果能写一个用例,在功能、自动化、性能三者的测试场景中重复使用,肯定能省去非常多的时间。
总体思路跟之前的接口和性能框架一样,通过总的测试项目中把接口功能封装好,留出来测试参数。功能测试就写方法调用然后人肉检查,自动化的话把接口响应拿出来,然后验证各种数据,性能直接使用性能框架直接调用该方法即可。
花了点时间,做了一个Demo,分享给大家。
这是一个简易的接口请求方法,其中main方法里面是功能测试执行代码,用例是文档形式,这里就不写了:
public class Headgear extends NajmBase {
public Headgear(NajmBase najmBase) {
this.loginKey = najmBase.loginKey;
this.args = najmBase.args;
this.user_id = najmBase.user_id;
}private static NajmBase base = NajmBase.getBase(0);
public static Headgear drive = new Headgear(base);
/**
* 当前正在使用的头套
*/public int usingHeadgearId;
// public JSONObject headgearInfo = new JSONObject();
public Map headgearInfo = new HashMap<>();
public static void main(String[] args) {
//NajmBase.getUserBalance(base.user_id);
//int type = 1, id = 36, packageId = 60, num = 1, price = 1;
//NajmBase base1 = new NajmBase(V580User.getUserName(0));
//Headgear headgear = new Headgear();
//headgear.switchHeadgear(34);
//output(headgear.getHeadgearInfo());
//output(headgear.getUsingHeadgearId());
//output(base1.loginResponse);
//drive.getAllHeadgear();
//new MallBase(base).buy(type, id, packageId, num, price);
//drive.getUserHeadgearInfo();
//NajmBase.getUserBalance(base.user_id);
//drive.getUserHeadgearInfo();
//drive.getOnsaleHeadgear();
int times = 0;
while (true) {
times++;
int type = 1, id = getRandomInt(2) == 1 ? 34 : 36, packageId = id == 34 ? 56 : 60, num = 1, price = 1;
long deadtime1 = drive.getHeadgearInfo().get(id);
Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
drive.getUserHeadgearInfo();
long deadtime2 = drive.getHeadgearInfo().get(id);
if (deadtime2 - deadtime1 != DAY) break;
}
output("一共进行了:" + times);
//output(drive.getHeadgearInfo());
//output(drive.usingHeadgear);
//output(drive.loginKey);
//output(drive.args);
//output(base.loginResponse.getJSONObject(DATAINFO).getJSONObject("headGear").getInt("id"));
testOver();
}/**
* 获取所有头套信息,包括下架的
*
* @return
*/
public JSONObject getAllHeadgear() {
String url = HOST + HeadgearApiPath.GET_ALL_HEADGEAR;
HttpGet httpGet = getHttpGet(url);
JSONObject response = getHttpResponseEntityByJson(httpGet);
output(response);
return response;
}/**
* 用户切换头套接口
*
* @param hid
* @return
*/
public JSONObject switchHeadgear(int hid) {
String url = HOST + HeadgearApiPath.SWITCH_HEADGEAR + hid + changeJsonToArguments(args);
HttpPost httpPost = getHttpPost(url);
JSONObject response = getHttpResponseEntityByJson(httpPost);
//output(response);
return response;
}/**
* 获取用户头套信息
*
* @return
*/
public JSONObject getUserHeadgearInfo() {
sleep(1);
String url = HOST + HeadgearApiPath.GET_USER_HEADGEAR;
JSONObject response = getHttpResponseEntityByJson(getHttpGet(url, args));
output(response);
if (isRightResponse(response)) {
headgearInfo.clear();
JSONArray jsonArray = response.getJSONArray(DATAINFO);
jsonArray.forEach(json -> {
JSONObject jsonObject = JSONObject.fromObject(json.toString()) ;
String name = jsonObject.getString("name") ;
long deadTime = jsonObject.getLong("deadlineTime") ;
int headgearId = jsonObject.getInt("goodId") ;
int use = jsonObject.getInt("isUse") ;
if (use == 1) usingHeadgearId = headgearId;
headgearInfo.put(headgearId, deadTime);
output(name, headgearId, getTimeByTimestamp(deadTime));
} );
}
return response;
}/**
* 获取在售的头套的列表
*
* @return
*/
public JSONObject getOnsaleHeadgear() {
String url = HOST + HeadgearApiPath.GET_ONSALE_HEADGEAR;
JSONObject response = getHttpResponseEntityByJson(getHttpGet(url, args));
output(response);
return response;
}public int getUsingHeadgearId() {
getUserHeadgearInfo();
return usingHeadgearId;
}public Map getHeadgearInfo() {
getUserHeadgearInfo();
return headgearInfo;
}}
下面是基于该功能的自动化测试用例,main方法里面是调试用例的过程,执行用例的方法在之前的文章写过,利用反射去记录用例信息和执行测试用例,并保存测试结果,输出测试报告,异常预警等等:
/**
* 用户0-10
*/
public class HeadgearCase extends SourceCode {
static HeadgearCase headgearCase = new HeadgearCase();
static NajmBase base = new NajmBase(V580User.getUserName(0));
static Headgear drive = new Headgear(base);
public static void main(String[] args) {
//headgearCase.testDemo001();
//headgearCase.testDemo002();
//headgearCase.testDemo003();
//headgearCase.testDemo004();
headgearCase.testDemo005();
//headgearCase.testDemo006();
ApiLibrary.testOver();
} /**
* 获取所有头套信息用例
*/
public void testDemo001() {
String label = "获取所有头套信息用例" + TAB + Thread.currentThread().getStackTrace()[1];
Verify verify = new Verify(drive.getAllHeadgear());
JSONObject result = new JSONObject();
result.put("状态码为0", verify.isRight());
result.put("包含数组", verify.isArray("heads"));
result.put("包含已下架的头套", verify.isContains("自动化专用3"));
result.put("包含正在出售的头套", verify.isContains("自动化专用1"));
MySqlTest.saveTestResult(label, result);
} /**
* 获取在售的头套用例
*/
public void testDemo002() {
String label = "获取在售的头套用例" + TAB + Thread.currentThread().getStackTrace()[1];
Verify verify = new Verify(drive.getOnsaleHeadgear());
JSONObject result = new JSONObject();
result.put("状态码为0", verify.isRight());
result.put("包含数组", verify.isArray("dataInfo"));
result.put("不包含已下架的头套", !verify.isContains("自动化专用3"));
result.put("包含正在出售的头套", verify.isContains("自动化专用1"));
result.put("包含描述信息", verify.isContains("测试10天"));
MySqlTest.saveTestResult(label, result);
} /**
* 获取用户头套信息用例
*/
public void testDemo003() {
String label = "获取用户头套信息用例" + TAB + Thread.currentThread().getStackTrace()[1];
Verify verify = new Verify(drive.getUserHeadgearInfo());
JSONObject result = new JSONObject();
result.put("状态码为0", verify.isRight());
result.put("用户头套正常", verify.isContains("自动化专用1"));
result.put("用户佩戴正常", verify.isContains("\"isUse\":1"));
result.put("头套套餐正常", verify.isContains("测试1天"));
MySqlTest.saveTestResult(label, result);
} /**
* 余额不足购买用例
*/
public void testDemo004() {
String label = "余额不足购买用例" + TAB + Thread.currentThread().getStackTrace()[1];
NajmBase base = new NajmBase(V580User.getUserName(1));
int type = 1, id = 36, packageId = 60, num = 1, price = 1;
Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
JSONObject result = new JSONObject();
result.put("状态码为35", 35 == verify.getCode());
MySqlTest.saveTestResult(label, result);
} /**
* 正常购买用例
*/
public void testDemo005() {
String label = "正常购买用例" + TAB + Thread.currentThread().getStackTrace()[1];
int type = 1, id = getRandomInt(2) == 1 ? 34 : 36, packageId = id == 34 ? 56 : 60, num = 1, price = 1;
int balance = NajmBase.getUserBalance(drive.user_id);
long deadtime1 = drive.getHeadgearInfo().get(id);
Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
drive.getUserHeadgearInfo();
long deadtime2 = drive.getHeadgearInfo().get(id);
int balance1 = NajmBase.getUserBalance(drive.user_id);
JSONObject result = new JSONObject();
result.put("状态码为0", verify.isRight());
result.put("截止日期正确", (deadtime2 + EMPTY).equals(verify.getValue("deadlineTime")));
result.put("头套日期增加正常", deadtime2 - deadtime1 == DAY);
result.put("用户余额减少正常", balance - balance1 == 1);
MySqlTest.saveTestResult(label, result);
} /**
* 用户切换头套用例
*/
public void testDemo006() {
String label = "用户切换头套用例" + TAB + Thread.currentThread().getStackTrace()[1];
drive.getAllHeadgear();
int id1 = drive.getUsingHeadgearId() == 34 ? 36 : 34;
Verify verify = new Verify(drive.switchHeadgear(id1));
int id2 = drive.getUsingHeadgearId();
JSONObject result = new JSONObject();
result.put("状态码为0", verify.isRight());
result.put("头套切换成功", id1 == id2);
MySqlTest.saveTestResult(label, result);
}
}
下面是一个针对其中某个功能的性能测试用例(测试用例分两种,一类是HTTP单次请求的,我才用了获取请求的HttpRequestBase对象然后去重新发送并发请求,一类是多接口或者非HTTP请求,如dubbo,mysql,redis,消息队列等等,直接调用的方法进行压测):
简单HTTP请求:
class CancelReason extends OkayBase{public static void main(String[] args) {
def argsUtil = new ArgsUtil(args)
def thread = argsUtil.getIntOrdefault(0, 2)
def times = argsUtil.getIntOrdefault(1, 5)def base = getBase()Headgear drive = new Headgear(base);
drive.getAllHeadgear()
def request = FanLibrary.getLastRequest()def timesthread = new RequestThreadTimes(request, times)
new Concurrent(timesthread, thread,"获取所有头套,内容流转二期压测接口").start()allOver()
}
}
非简单HTTP请求的请参考之前写过的性能测试框架Demo:性能测试框架第二版。这类方法写起来比较简单,使用范围很高,但是需要根据不同的业务需求解决多线程数据和对象的安全问题。
整个项目放在git上,功能测试在本地,自动化项目和性能项目在服务器,采用Groovy脚本运行,也可以在本地调试。自动化项目采取定时或者间隔固定时间自动运行,性能项目收到输入命令groovy filename.groovy来运行。
文章图片
最后我也整理了一些软件测试学习资料,对于自学软件测试的小伙伴来说应该会很有帮助,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer,这份资料也已经帮助了很多的软件测试的学习者,希望也能帮助到你。需要公众号:软件测试小dao 自取。软件测试,与你同行!陪你成为优秀的测试工程师!
既然都看到这里啦,请你帮个忙:
1、点赞,让更多小伙伴看到;
2、关注我,持续更新测试干货。
干货分享 自动化测试6年后,终于有了属于我自己的团队···
如果你35岁恐慌了,那你真的该反思自己了···
活久见!40W年薪低?35岁测试工程师惨遭女孩嫌弃!估计是被鸡汤洗脑了!
【测试用例|如何统一接口测试的功能、自动化和性能测试用例】迷茫了3年:做完这个测试项目,我终于决定辞职···
文章图片
推荐阅读
- Python开发|利用re实现修改测试用例格式——python实现
- 软件测试面试必问(fiddler 在工作中有哪些应用(怎么破?))
- 1024程序员节(51CTO博客送福利啦,千件实体好礼,零门槛瓜分;;;)
- 软件测试|目前最受欢迎的12个Python web框架,你用过几个()
- 做软件测试需要一直培养成长的技能
- web前端|常见的10道Web前端面试题及答案分享!
- 软件测试之测试工程师如何交接项目
- 走进Java接口测试之日志框架Logback
- 走进Java接口测试之流式断言库AssertJ