目录
一、环境说明
涉及到项⽬环境和测试⼯具环境
1、项目环境搭建
第三方接口通过mock解决
2、Mock说明
什么是mock?
- 模拟接⼝
- mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,这个虚拟的对象就是 mock 对象,mock 对象就是真实对象在调试期间的代替品
什么场景下会⽤mock?
- 依赖的接⼝未实现
- 依赖的接⼝响应速度慢
- 针对接⼝模拟各种异常
如何去实现?
- 使⽤mock现有⼯具moco
- ⾃定义mock
- ① 编写⼀个函数直接return 模拟的值
- ② 使⽤接⼝开发框架编写要模拟的接⼝ flask
要模拟哪些内容?
- 响应数据
- 响应状态码
需求场景:
- 模拟⼀个:登录接⼝
- 1、在API⽂档中说明如果登录成功,返回:状态码:200 {"status":200,"msg":"登录成 功!","token":"XXX1213123123"}
- 2、登录失败反馈:状态码:200 {"status":100,"msg":"⽤户名或密码错误!"
- 问题:开发还未实现登录接⼝,那么依赖登录如何解决?
案例:
python
from flask import Flask
app = Flask(__name__)
# 定义接口 模拟正常返回结果,默认状态码200
@app.route("/login",methods=["get"])
def login():
return {"status":200,"msg":"登录成功!","token":"XXX1213123123"}
# 定义接口 模拟异常返回结果,状态码401
@app.route("/login/shibai",methods=["get"])
def shibai():
return {"status":401,"msg":"登录失败!"},401
app.run()
扩展:
- ⽤户名为admin 密码为:123456 返回登录成功!否则返回⽤户名或密码错误,请求参数格式为:form
python
from flask import Flask,request
app = Flask(__name__)
"""
需求: ⽤户名为admin 密码为:123456 返回登录成功!否则返回⽤户名或密码错误,请求参数
格式为:form
"""
# 定义接口
@app.route("/login",methods=["post"])
def login():
username = request.form.get("username") # 获取表单数据的消息体
password = request.form.get("password")
if username == "admin" and password == "123456":
return {"status":200,"msg":"登录成功!","token":"XXX1213123123"}
else:
return {"status": 401, "msg": "用户名或密码错误!"}
app.run()
在jmeter中发送带消息体的post请求,就可以测试自定义的接口
本项目中需要mock的接口:
二、构造测试数据
⽅式:
- 通过系统⻚⾯构造
- 通过接⼝构造
- 通过数据库构造
1、通过系统页面构造
优点:可视化⻚⾯操作
缺点:操作步骤较多,不适合频繁改造数据。
示例:参考发布借款标流程
2、通过接口构造
优点:速度快
缺点:接⼝耦合度⾼(接⼝之间依赖性强,⼀个失败,后⾯全失败)
建议:适合依赖3个以内接⼝
3、通过数据库构造【推荐】
优点:灵活度⼤,执⾏速度最快。
缺点:需要熟悉库、表、字段
建议:编写SQL语句时,使⽤复制⽣成的SQL语句,修改主要字段值
【小结】
4、案例:构造借款业务数据
sql
-- 清空操作
delete from `czbk_member`.`mb_member` where id=869;
delete from `czbk_member`.`mb_member_info` where id=987;
delete from `czbk_finance`.`fn_loan_amount` where id=987;
delete from `p2p_mock`.`p2p_account` where id=911;
-- 借款
delete from `czbk_finance`.`fn_loan` where id=642;
delete from `czbk_finance`.`fn_loan_info` where id=832;
delete from `czbk_finance`.`fn_loan_amount_log` where id=869;
INSERT INTO `czbk_member`.`mb_member` (`id`, `name`, `trust_account`, `password`,
`email`, `phone`, `paypassword`, `count`, `register_ip`, `register_time`,
`register_date`, `lastlogin_ip`, `lastlogin_time`, `lastlogin_date`,
`register_type`, `role`, `group`, `group_status`, `is_realname`, `is_email`,
`is_phone`, `is_video`, `is_id5`, `is_vip`, `credit_point`, `is_auto`,
`pwd_attach`, `status`, `lock_time`, `vip_start_time`, `vip_end_time`,
`vip_category_id`, `vip_category_ind`, `amount`, `phonestr`) VALUES ('869',
'13099775533', '6021234507160403', 'eab70f4a46c640b3dfc35040bf37c803', NULL,
'13099775533', NULL, '1', '1972826569', '1588835827', '2020-05-07', '1972826569',
'1588835827', '2020-05-07', '1', '1', '1', '2', '1', '-1', '1', '-1', '-1', '-1',
'0', '-1', '1m4U82PqPx', '1', NULL, NULL, NULL, NULL, NULL, '0.00', NULL);
INSERT INTO `czbk_member`.`mb_member_info` (`id`, `member_id`, `member_name`,
`avatar`, `nickname`, `realname`, `gender`, `birthday`, `card_id`, `qq`,
`educational_background`, `marry_status`, `graduated`, `company_industry`,
`company_scale`, `company_office`, `monthly_income`, `invite_money`,
`hometown_province`, `hometown_city`, `hometown_area`, `hometown_post`) VALUES
('987', '869', '13099775533', NULL, NULL, '⼩⽯头', NULL, '1986-11-18',
'429009118611181111', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
INSERT INTO `czbk_finance`.`fn_loan_amount` (`id`, `member_id`, `member_name`,
`credit_amount`, `credit_amount_freeze`, `vouch_amount`, `vouch_amount_freeze`,
`pawn_amount`, `pawn_amount_freeze`, `roam_amount`, `roam_amount_freeze`) VALUES
('987', '869', '13099775533', '200000.000000', '0.000000', '0.000000',
'0.000000', '0.000000', '0.000000', '0.000000', '0.000000');
INSERT INTO `p2p_mock`.`p2p_account` (`id`, `account`, `AvlBal`, `AcctBal`,
`FrzBal`, `create_time`) VALUES ('911', '6021234507160403', '0.00', '0.00',
'0.00', '2020-05-07 16:04:03');
-- 借款
INSERT INTO `czbk_finance`.`fn_loan` (`id`, `ind`, `serialno`, `name`,
`member_id`, `member_name`, `amount`, `credited_amount`, `progress`,
`tender_count`, `category_id`, `category_type`, `repay_type`, `period`, `apr`,
`sort_index`, `sort_top`, `status`, `hidden_status`, `additional_status`,
`deposit_certificate`, `certificate_file_id`, `loan_repay_status`,
`loan_repay_time`, `overdue_time`, `add_date`, `add_time`, `verify_time`,
`reverify_time`, `add_ip`, `vouch_company_id`, `op_status`, `marker_type`) VALUES
('642', 'f5380d59791773a8abad4141ff90a5a4', '202008231111', '数据库构造借款1',
'869', '13099775533', '100000.00', '0.00', '0.00', '0', '1', '1', '1', '60',
'7.55', '1', NULL, '3', '1', '-1', '-1', NULL, NULL, NULL, '1609501013', '2020-
05-07', '1588847800', '1588851413', NULL, '1972826569', '0', '-1', '数据库');
INSERT INTO `czbk_finance`.`fn_loan_info` (`id`, `loan_id`, `thumbs`, `contents`,
`attachment_ids`, `password`, `use`, `tender_amount_min`, `tender_amount_max`,
`freeze_amount`, `freeze_amount_proportion`, `freeze_period`, `award_status`,
`fail_award_status`, `award_amount`, `award_proportion`, `award_amount_total`,
`validate`, `part_status`, `tender_count`, `comment_status`, `comment_count`,
`is_company`, `company_name`, `vouch_company_info`, `vouch_company_pic`,
`vouch_company_guaranty`, `amount_category_id`, `hits`, `cancel_admin_id`,
`cancel_remark`, `cancel_time`, `verify_admin_id`, `verify_admin_name`,
`verify_remark`, `verify_time`, `verify_ip`, `reverify_admin_id`,
`reverify_admin_name`, `reverify_remark`, `reverify_time`, `reverify_ip`,
`auto_scale`, `is_auto`, `additional_status`, `additional_apr`,
`additional_name`, `additional_amount_max`, `additional_pic`, `product_process`,
`information`) VALUES ('832', '642', NULL, '数据库构造借款1', 'a:0:{}', NULL,
'10102', '100.00', '1000.00', NULL, '10.00', NULL, '-1', '-1', NULL, NULL, NULL,
'239', NULL, '0', '-1', '0', '-1', NULL, NULL, NULL, NULL, '1', '1', NULL, NULL,
NULL, '4', 'admin', '数据库构造借款1 通过', '1588851413', '1972826569', NULL, NULL,
NULL, NULL, NULL, NULL, '1', '-1', '0.000000', NULL, '0.000000', NULL, NULL,
NULL);
UPDATE `czbk_finance`.`fn_loan_amount` SET `credit_amount_freeze`='100000.000000'
WHERE `member_id`='869';
INSERT INTO `czbk_finance`.`fn_loan_amount_log` (`member_id`, `member_name`,
`category_id`, `type`, `amount`, `remark`,
`add_time`) VALUES ('869','13099775533', 1, 4, '100000', '借款冻结',
'1972826569');
三、JMeter执行接口测试用例
按照 金融项目实战 02|接口测试分析、设计以及实现-CSDN博客 中的用例来执行接口测试用例
下文内容可以结合测试项目实战--安享理财2(Jmeter接口测试)_安享理财数据库-CSDN博客中的"四、手工执行接口测试",这篇博客里写了其他的注意事项。
1、获取图片验证码、获取短信验证码
设置这个,之后就用取样器发送请求就不用填域名了
注意:
1、随机数为空、随机数为字符串,响应状态码为400、404,如果需要查看结果树的该请求变绿,就需要加断⾔且勾选"忽略状态"(图中截图示例)
2、接口中的随机小数也可以函数来随机生成,借助函数助手对话框
3、获取短信验证码依赖图⽚验证码,需要先请求图⽚验证码,添加cookie管理器进⾏关联。该cookie管理器会自动管理cookie,只要域名相同,上条接口会自动保存cookie,下一条接口需要cookie会自动附加。
2、注册脚本
提示:
1、密码为空、未同意条款为bug。
2、注册接口中手机号必须和获取短信验证码接口手机号⼀致。原因是需要保持前后cookie一样 。
3、登录脚本
提示:
1、解锁需要使⽤固定定时器登录60秒 (60000毫秒)
2、查询登录状态(未登录)需要把登录请求删除
【补充】两种请求体格式
multipart/form-data
普通form
4、实名认证
1、一定要勾选红框内容,因为aip文档中要求的请求头是multipart/form-data;
2、不能在测试计划下面加请求头默认值,不然会勾选multipart/form-data失效,导致报错;
3、每个认证测试接口中的登录账号必须不一样,因为每个认证过的接口认证信息已经保存了
5、请求第三方开户
红框是从上一个开户接口的响应信息里复制粘贴的;
蓝框是从上一个开户接口的响应信息里用正则表达式提取的变量
难点:分析正则提取公式
结论:黄框是要提取的数据,除了要提取的数据不⼀样,其他内容格式都⼀样
表达式编写:用自带的正则表达式测试器,测试以下能不能提取到正确的内容
这里显示的数据是unicode编码后的响应数据
扩展 unIcode编码
6、获取充值验证码、充值、第三方充值
提示:
1、后台充值必须先登录,再请求图⽚验证码,最后调⽤后台充值
2、三⽅充值和三⽅开户⼀模⼀样,直接复制即可。
7、投资
提示:投资id使⽤642,密码为空的使⽤id是820。