1.接口自动化框架搭建

Python+pytest+requests+openpyxl+pymysql+logure+allure+jenkins
分为common层 testcases层 testdatas层 conf层 outPuts层
common层:工具类,读取Excel,存放文件的路径,连接数据库并进行查询,接口请求,存放数据,数据替换,结果断言,装饰器
testcases层:测试案例,conftest.py中夹具共享
testdatas层:管理测试用例数据
conf层:配置文件,存放全局数据和一些容易变动的数据
outPuts层 :日志输出
main.py:案例执行入口(收集用例,执行用例,生成报告)

2.常用的库

requests、pytest、openpyxl、pymysql、logger、jsonpath、re、allure

3.接口关联的处理

   接口中的返回值利用jsonpath提取动态存储到类属性中,当其他接口需要用到时,再提取出放到请求参数中

4.数据驱动

相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离,利用第三方库pytest的装饰器实现数据驱动@pytest.mark.parametrize(“case”, cases)

5.数据的存放

  • 对于账号密码,系统url,数据库信息,这种管全局的参数,单独抽出来,写的配置文件里(如ini)
  • 对于一些一次性消耗的数据,比如注册或新增文章标题,每次注册或新增都是不一样的数,可以用随机函数生成,比如python的一个第三方模块faker,创建一些测试用的随机数据
  • 对于一个接口经常更改的数据,可以参数化,数据放yaml
  • 对于不经常改的的数据。 可以用数据驱动方式,用excel管理测试的接口数据
  • 对于需要依赖于上个接口的数据存放在动态属性中

6.json和字典dict的区别

字典是python语言的一种数据类型, json是一种轻量级的数据交换格式,在网络中传输的通用数据。json本质上还是字符串,只是按key:value这种键值对的格式来的字符串

7.并发测试

一般是利用第三方插件pytest-xdist,前提是用例之间没有依赖关系且执行是没有顺序的,所以不适合接口自动化

8.失败重试

有利于提高自动化用例的稳定性,可以通过pytest的pytest-rerunfailures插件来实现用例重跑,具体有两种形式,一种是全局通过命令行: Pytest --reruns 2 --reruns-delay 5,一种是局部在案例方法上打标记@pytest.mark.flaky(reruns=2, reruns_delay=1)

9.遇到的问题

(1) 用例的入参过多时不小心有了空格,会报参数错误, 解决:case_str=case_str.replace(“\n”, “”).replace(“\r”, “”)#Enter = 回车+换行(\r\n)
(2)读取excel案例时,excel中整个空行有的也被读取了,导致读取执行时多执行了一条案例且这条案例报错.
解决:根据行获取列,循环列获取单元格中的值,如果有一个单元格有值,就代表这一行可取,如果都是空则不可取
在这里插入图片描述
(3)删除刚刚新增的数据时发现新增的接口返回值没有特定的标记,导致删除接口时入参不能确定就是刚新增的数据
解决:
获取数据库表中最新的一条数据,进行删除(弊端,有可能把别人的数据删掉);
找开发把新增接口返回值标记加下

*10.提高案例执行的稳定性

  • 执行时间,半夜定时执行
  • 增加重试机制,排除环境干扰因素

11.做接口测试过程中发现过哪些bug?

短信群发功能,新建群发-短信类型选择直播短信时,直播时间前端合代码覆盖了,所以点击确定,没有请求接口,无反应

12.pytest的优势

  • 直接使用assert进行断言
  • 失败用例提供非常详细的错误信息
  • 自动发现和收集测试模块和用例
  • 灵活的fixture管理
  • mark用例标记
  • 丰富的插件系统
  • 支持失败重试
  • 兼容了unittest

13.get和post的区别

  • 作用:get 获取资源 post 创建资源
  • 请求主体: get 无请求主体 post 有请求主体
  • 幂等性:get 幂等 post 非幂等
  • 缓存: get可以缓存 post 一般不缓存
  • 历史记录和书签: get 可存放 post 不可
  • 安全性 get 低 post 高

14.三次握手

  • 第一次握手时,客户端向服务端发送网络包,服务端收到后确认收到信息,主要目的确认客户端发送功能、服务端接收功能是正常的
  • 第二次握手时,服务端向客户端发送网络确认收到报文,客户端接收,主要目的是确认服务端发送功能、接收功能正常、客户端接收功能、发送功能正常,但此时,服务端是不知道客户端的接收功能是否是正常的,因为没有返回信息来告诉它
  • 第三次握手时,客户端发包,服务端接收,主要目的是确认客户端的接收、发送功能正常,服务器自己的发送、接收功能正常

15.http状态码

  • 2XX,表示请求被正确处理
    200:请求被正确处理
    204:请求被受理但无资源返回
    206:客户端只请求资源的一部分
  • 3XX,表示需要进一步操作(重定向)
    301:永久性重定向
    302:临时重定向
    303:与302类似,只希望客户端在请求一个URI时,能通过GET方法重定向到另一个URI上
    304:发送附带条件的请求时,条件不满足时返回,与重定向无关
    307:临时重定向,与302类似,只是强制要求使用POST方法
  • 4XX,一般都是客户端相关问题
    400:请求报文语法有误,服务器无法识别
    401:请求需要认证
    403:请求的对应资源禁止访问
    404:服务器找不到对应资源
  • 5XX,一般是服务器端相关问题
    500:服务器内部错误
    503:服务器正忙

16.接口自动产生的垃圾数据

1.数据库断言会把一条案例断言结果Ture或False放在一个字典里,为了不影响下条案例的断言结果,每条用例执行完后,需要清空对比结果,这时需要利用pytest的confest.py中装饰器@pytest.fixture的后置函数yield把字典置空
2.数据库脏数据一般都是新增接口导致的,所以新增成功后可以执行删除接口把新增的数据删除,(注意:如果新增接口返回值没有具体的内容,这时要利用数据库获取最新的一条数据(SELECT * FROM 数据库名.表名 t ORDER BY t.创建时间 DESC LIMIT 1 ;),有个弊端就是有可能把别人的数据删掉,所以尽量跟开发沟通新增接口返回值里有个标记)
3.专门有一个自动化数据库,定期清除数据

17.unittest和pytest的区别

1.用例设计规则
unittest:
(1)试类必须继承unittest.TestCase
(2)测试函数必须以”test_”开头
pytest:
(1)测试文件的文件名必须以”test_”开头,或者以”_test”结尾
(2)测试类命名必须以”Test”开头
(3)测试函数名必须以”test”开头
2.断言
unittest:
assertXXX
pytest:
直接使用assert进行断言
3.用例前置和后置
unittest:
(1)通过setup每个用例执行前执行,teardown每个用例执行后执行
(2)通过setupclass类里面所有用例执行前执行,teardownclass类里面所有用例执行后执行
每个测试文件必须单独设置前后置
pytest:
通过fixture夹具可以自定义pytest的前置和后置,yield之前是为前置,yield之后为后置,格式@pytest.fixture(scope=“XXX”),scope:有四个级别,function(默认),class,module,session
创建conftest.py文件,当前目录下所有的测试文件都能自动调用该夹具
4.参数化
unittest:参数化需要依赖第三方库,使用ddt去做参数化
pytest:通过装饰器@pytest.mark.parametrize来实现
5.报告展示
unittest:通过HTMLTestRunner生成
pytest:可以集成allure插件生成
6.失败重运行
unittest:不支持
pytest:pytest --reruns=2(2表示重运行2次)
7.挑选用例执行
unittest:不支持
pytest:
(1)创建一个pytest.ini文件,
[pytest]
markers = demo(标记名) : just for display(备注名,如果不写 可以不加冒号)
(2) 在要执行的测试用例/测试类前面加上: @pytest.mark.标记名
(3)main.py文件中添加[-m ,‘要执行用例的标签名’] 根据标签名筛选用例并执行
8.安装需求不同
pytest为第三方单元测试库,需额外安装;unittest为标准库,无需额外安装

18.pytest跳过测试用例

1.无条件跳过------@pytest.mark.skip()
在测试方法或类前面加上装饰器@pytest.mark.skip(reason=None),表示该条测试用例不执行,参数reason代表跳过的原因,reason可省略
2.有条件跳过------@pytest.mark.skipif()
@pytest.mark.skipif(condition, reason=“xxx”)
说明:condition—跳过的条件,如果为True则跳过该函数,如果为False则不跳过

19.测试用例执行流程

全局:测试报告清除处理,测试账号准备-》打开Excel,读取对应的接口测试数据 -》 定义一个测试类:写接口的测试用例,使用pytest的数据驱动 -》 处理请求数据,若有替换就替换 -》发起请求,有token就传token -》得到响应结果 -》如果有提取字段,那么需要从响应结果当中,提取对应的数据 -》响应结果断言 -》数据库断言

20.数据库断言遇到的问题

【条数比较】
用例里:
{"check_type":"count","check_sql":"select * from licaishi_td.bx_product_unique_name where name='#attrtext#'","expected":{"count":1}}
代码运行:
check_sql_str ='{"check_type":"count","check_sql":"select * from licaishi_td.bx_product_unique_name where name=\'精华84661108\'","expected":{"count":1}}'
【值比较】
用例里:
{"check_type":"value","check_sql":"select name from licaishi_td.bx_product_report_name where name='#attrtext#'","expected":{"name":'#attrtext#'}}    # '#attrtext#'应该用双引号
代码运行:
check_sql_str = '{"check_type":"value","check_sql":"select nachame from licaishi_td.bx_product_unique_name where name=\'自己46822194\'","expected":{"name":\'自己46822194\'}}'

需要把代码运行后的 字符串格式 转换成 字典,有以下两种格式

  1. check_sql_dict = eval(check_sql_str)
  2. check_sql_dict = json.loads(check_sql_str) #接口返回值有null用这个,例如{“code”: 0, “msg”: “成功”,“data”:“null”}
    当【值比较】时,用第2种报错了,原因是 案例中有单引号,而json.loads不认单引号,json中的字符串需要用双引号包起来

21:遇到接口入参是的字段是对象时
例如:接口请求:
[{‘pay_period’:‘3’}] 单引号 和 [{“pay_period”:“3”}]双引号 和 [{“pay_period”:“3”}]
双引号正常 和 斜杠 双引号(接口里用这个)正确:
在这里插入图片描述

单引号不正常,无基础配置等按钮了,前端报错
前端字符串转json 估计有些写法不能兼容单引号
在这里插入图片描述
22.接口响应慢的原因
1.网络异常:如果应用程序需要向远程服务器发送网络请求,而网络速度很慢或者请求的服务器响应时间很长,那么就会导致接口请求时间变长
2.缓存问题:缺乏适当的缓存机制也会导致响应时间变慢。如果接口发生大量的重复请求,而服务器没有缓存这些请求结果,每个请求都需要重新计算,导致响应时间变。
3.硬件问题:服务器硬件或存储设备的故障可能导致响应时间变慢。例如,硬盘空间不足或硬盘崩溃可能导致数据访问变慢
4.数据库查询,数量过大或者关联多个表
5.第三方接口,第三方接口响应时间很长或者出现错误,那么就会导致应用程序的接口请求时间变长
6.代码逻辑,在某些情况下,代码逻辑可能会导致程序进入死循环或者长时间阻塞状态,从而导致接口请求时间变长
7.接口过载:在一段时间内,如果接口有太多的并发请求,服务器可能会过载,导致响应时间变慢,或者服务不可用。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐