接口测试

接口测试流程

  1. 业务需求分析
  2. 看接口文档
    • 文档形式:pdf、excel、html、doc、swagger
    • 接口4要素
      • 请求地址 http://ip地址:端口号/项目地址
      • 请求方法 http – [get、post、delete、put、option]
      • 参数传递
        • URL参数
        • Body请求体(json、文件)
        • header 请求头 【例如:有些系统使用token】
      • 响应内容【接口测试结果判定】
  3. 测试用例设计
  4. 用例执行【被自动化替代】
  5. 报告总结输出 【被自动化替代】

自动化测试 不是为了取代手工测试,而是为了提高测试效率,降低测试成本【降本增效】

接口测试人员只需要关注测试的设计,后续的步骤由框架替代

自动化框架的设计注意事项:

  1. 框架是普通自动化脚本开发和测试开发的分水岭
  2. 框架的特点【复用】

框架开发步骤(针对测试人员去开发系统软件)

  1. 开发一个框架的需求
    • 录入接口测试用例信息 到测试工具
    • 借助测试工具(postman、jmeter等等)发起接口请求
    • 获取接口响应内容,判定测试结果
    • 测试报告的输出

这里需要安装allure,allure是用于生成测试结果文档的

在下载了allure的官网压缩包之后,将其解压并配置环境变量到PATH目录上,配置bin目录即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import xToolkit, requests, pytest, allure, os

# 一行代码读取所有测试用例信息
# 读取接口测试用例.xls中的2表的数据,sheet=1表示表2
allTest = xToolkit.xfile.read("接口测试用例.xls").excel_to_dict(sheet=1)

print(allTest)


# 借助测试工具(postman、jmeter等等)发起接口请求
@pytest.mark.parametrize("testOne", allTest)
def test_case_exec(testOne):
res = requests.request(
url=testOne["接口URL"],
method=testOne["请求方式"],
params=eval(testOne["URL参数"]))
# 断言测试是否通过,一般是通过测试用例的预期状态码和实际响应的状态码进行比较
print(res.text)


# pytest 运行方式 1.命令行 2.代码中调用[框架封装常用]
if __name__ == "__main__":
pytest.main([
'-s', # 打印print 输出的内容
'-v', # 打印详细运行日志信息
'--capture=sys' # 保留系统输出
'test.py',
'--clean-alluredir','--alluredir=allure-results' # 生成 测试数据-用于生成html报告
])
# allure html报告生成的技术 1.生成测试数据 2.通过allure命令生成html报告
os.system(r"allure generate -c -o 测试报告")

上述代码就实现了对应的功能

Jmeter接口自动化测试

接口测试_技术背景:前后端分离架构、移动互联网时代(app、小程序、公众号h5…)

测试人员依赖各种工具:web应用使用浏览器、接口测试【通过工具模拟客户端调用】

接口文档核心要素

我们对一个接口做测试,填入以下参数,这是一个登录接口,接着我们可以通过查看结果树获取结果

image-20240616154823873

在参数填写正常的情况下,都是没有任何问题的

结果如下:

1
{"msg":"登录成功","code":0,"data":{"id":"5435","username":"lisi","nickname":"","mobile":"","email":"","avatar":"http:\/\/shop-xo.hctestedu.com\/static\/index\/default\/images\/default-user-avatar.jpg","alipay_openid":"","weixin_openid":"","weixin_unionid":"","weixin_web_openid":"","baidu_openid":"","toutiao_openid":"","qq_openid":"","qq_unionid":"","integral":"0","locking_integral":"0","referrer":"0","add_time":"1644236740","add_time_text":"2022-02-07 20:25:40","mobile_security":"","email_security":"","user_name_view":"lisi","is_mandatory_bind_mobile":0,"token":"89b498190522bc05a2d966b6fbda0fc4"}}

此时我们再测试另一个,复制刚刚登录的接口,修改一些参数

路径:/index.php?application=app&s=/api/order/index

将之前的参数删除,添加json数据

1
2
3
4
{
"page":1,
"status":"-1"
}

再次运行,此时报错400,说明是没有权限,我们需要添加权限,也就是token

修改路径:/index.php?application=app&s=/api/order/index?token=89b498190522bc05a2d966b6fbda0fc4

添加了token后再次运行,即可返回结果,但返回的结果没有进行格式化,看起来很难受,我们需要对其进行格式化

实现步骤

  1. 下载jar包(jackson-annotations,jackson-core,jackson-databind 版本都为2.8.6);

  2. 将jar包所在的目录添加到Test Plan 测试计划中;

  3. 在Jmeter的测试计划Test Plan 中添加 BeanShell PostProcessor;

  4. 在BeanShell PostProcessor 中的Script中插入代码;

  5. 重启Jmeter;

详细步骤:

我们需要先下载三个maven的包(jackson-annotations,jackson-core,jackson-databind 版本,我这里选择的是2.15.2),在该网址进行下载:https://mvnrepository.com/search?q=jackson-annotations

将jar包添加到Test Plan测试计划中

image-20240616160941616

在Jmeter的测试计划Test Plan 中添加 BeanShell PostProcessor;

路径:选中Test Plan > Add > Post Processor > BeanShell PostProcessor添加;

image-20240616161320104

在BeanShell PostProcessor 中的Script中插入代码;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;


try {

String response_data = prev.getResponseDataAsString();

log.info("response_data: " + response_data);
ObjectMapper objectMapper = new ObjectMapper();

Map readValue = objectMapper.readValue(response_data, Map.class);
String writeValueAsString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(readValue);
log.info("PrettyFromatJson result: " + writeValueAsString);

prev.setResponseData(writeValueAsString);

} catch (JsonProcessingException e) {

log.info("BeanShell PostProcessor failed=======================================", ex);

}

重启jmeter则解决

上述方法借鉴于:https://blog.csdn.net/ueiun2_explore/article/details/103729730

大项目协同方式

大型项目:分模块,划分功能–

  • 分别编写测试脚本,多个测试 协同测试

A:用户登录注册模块

B:订单模块测试脚本(需要登录)

C:购物车测试模块(需要登录)

如何避免重复的工作,相互之间的协作问题

测试片段可以单独划分每一个模块,对于测试用例模块化封装,通过模块控制器对于对应的测试片段进行执行

image-20240616210445433

Jmeter自动化问题及解决方案

自动化是什么?

自动化不是特指某一个技术。凡是能够提高测试人员效率、替代部分人工操作的技术

如何提高效率,分析效率低

  • 举例:测试对应环境【开发环境、测试环境、UAT、准生产/预发布/灰度】每一次换环境,需要手工去修改每个接口地址
  • 解决:用户自定义变量
  • 变量改动之后,接口调用自动引用最新的数据
  • 自动化的最初体现

添加一个全局的测试变量

image-20240616212002058

在此处添加变量

image-20240616212123640

添加完成后,通过${}的形式可以使用对应的变量

image-20240616212238809

多组数据测试

  • 举例:登录场景,不同的数据组合 不同的测试用例

    • 正向、异常、【边界值、等价类划分】
  • 手工:多组数据要进行多次修改,然后执行测试

  • 解决:数据驱动测试(DDT)

    • csv数据读取:数据单独保存起来(测试所需要的数据保存起来)
    • 循环控制器:
    • DDT数据和测试脚本分离【1、测试执行需要的参数变量 2、结果判断的预期值】
  • 自动化测试 – 根据数据组的数量,自动化发起多次调用

有时候我们可能对多组数据进行测试,例如登录的多个用户的情况

  • 密码正确 用户名正确 登录成功
  • 密码错误 用户名正确 登录失败

以及其他的情况

我们可以通过读取csv的形式读取多组数据,然后将多组数据赋到对应的参数上

image-20240616214600657 image-20240616214613429

我们将参数通过${}的形式赋到对应的位置上

此时运行,会发现有对应的结果,但是只有第一组数据的结果,并没有多组数据的结果

此时需要循环控制器进行控制

image-20240616215013475

接着将csv和登录接口的功能放入到循环控制器中,循环控制器会对其进行循环

再次运行,即可看到对应的结果了

接口执行结果判定

  • 手工测试:肉眼人工一个个去看结果。

100个接口,每个接口5个用例,500个用例的执行结果

  • 解决:断言机制
  • 自动化测试:利用软件自动化判断响应结果是否正常

【特定状态码、和数据库对比、判定响应内容…】

image-20240617084654544

image-20240617084949232

接口依赖处理

  • A接口依赖B接口返回的值
  • 例如:token,登录的token可以给其他参数进行使用
  • 解决方法:提取器
  • 提取前一个接口的数据作为变量,后续接口中引用该变量
image-20240617105759835

通过json后置提取器来进行数据的提取

先在订单处放置对应的提取结果名/index.php?application=app&s=/api/order/index?token=${login_token}

image-20240617110222422

加密接口测试

不能用未处理的明文数据进行接口调用

明文数据传输在网络 – 安全性降低【很有可能被截取】

案例1:记录网络数据传输内容【野生免费wifi】

案例2:用别人的VPN梯子,外网【代理 – fiddler、Charles】

软件服务商,增强安全性

如果我们想对加密接口进行测试,该怎么处理呢

  1. 准备测试数据的时候,提前做好加密处理。【数据不怎么变动的场景】
    1. 让开发生成一些加密数据。局限性:数据是固定的
  2. 了解开发人员用的加密算法+密钥,自己写代码进行加密【绝大多数测试不会加密】
    1. md5 – hash算法,摘要算法,(不可逆加密)
    2. 对称加密
    3. 非对称加密
  3. 开发人员提供API的调用方式【示例代码】
    1. beanshell – 类似java语言【不推荐,是一种脚本,容易写错且不好找出问题】
    2. 最大问题:理论上是可行的,但是实际落地极其麻烦
  4. 提供可执行的命令工具【比较好】
    1. 在线加解密接口【适合比较通用的加密场景】【依赖外部的工具网站能够使用】
    2. 让开发提供内部加解密接口【弊端:产生额外的接口调用,不适用性能测试场景】
    3. 本地可执行文件【比较通用】 – openssl、自己开发编写
    4. 通过OS进程采样器实现Jmeter与任意开发语言,任意工具进行集成

OS进程取样器

介绍:jmeter去执行一段命令(例如python的),拿到返回结果

image-20240619200622686

操作方式

image-20240619201540708

上面这段内容是对用户名和密码进行加密后返回,比如说我们想在登录中使用这个结果该如何使用呢

这里需要使用正则表达式提取器

将对应的结果来进行提取

在接口中创建正则表达式提取器

image-20240619203340625

通过正则表达式匹配可以匹配到对应的数据

image-20240619210421464