1-什么是接口测试
接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点,定义特定的交互点,然后通过这些交互点来,通过一些特殊的规则也就是协议,来进行数据之间的交互。
接口测试是功能测试的一种。它主要借助于单元测试技术,通过模拟上层应用或者系统上层调用接口的应用场景,是对系统接口功能进行测试的一种手段。在进行接口测试的过程中,测试工程师并不需要了解被测试系统的所有代码,而主要通过分析接口定义以及模拟接口调用的业务应用场景来进行测试用例的设计,从而达到对被测试系统功能进行测试的目的。接口测试的重点是要检查数据的交换、传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
2-接口测试的意义
1)更早的发现问题 接口测试可以在功能界面未开发出来之前对系统的接口进行测试,从而更早的发现总是并以更低的成本修复问题。
2)缩短产品周期 接口测试更早的介入,可以更早的发现并解决 bug,从而使得留到后期功能测试阶段的 bug 数量减少,最终缩短整个项目的上线时间,有助于实现敏捷测试。
3)发现更底层的问题 系统中的有些 bug 如果想通过 UI 层功能测试会比较困难,或者构造测试数据和测试条件非常复杂,而通过接口测试可以更简单、更全面的覆盖到底层的代码逻辑,从而发现一些隐藏 bug。尤其是一些异常的、极端的情况,可以用接口测试很容易的验证。
3-接口的分类
1)webService接口 (如soup、rmi、rpc协议)
2)http api 接口 http协议
4-http请求方式
1)Get 发送请求来获得服务器上的资源,请求体中不会包含请求数据,请求数据放在协议头中
2)Post 向服务器提交资源让服务器处理,比如提交表单、上传文件等,可能导致建立新的资源或者对原有资源的修改。提交的资源放在请求体中
3)Put 发送资源与服务器,并存储在服务器指定位置,要求客户端事先知道该位置,指定需要更新的资源的URI本身,对其内容进行覆盖
4)Delete 请求服务器删除某资源
5)Patch Patch 方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新
5-http状态码
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理 创建成功 201 删除成功204
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求 401 没有权限 404 没有找到资源 一般请求地址错误
5** 服务器错误,服务器在处理请求的过程中发生了错误
6-接口测试用例设计
基础数据 用户 角色 权限 设备等接口 主要涉及 新增 获取 修改 删除 可根据其入参的字段 针对字段 是否必填(字段必填/值必填) 参数长度校验(非空/长度/边界值) 参数有效性-(是否存在 是否有效) 参数组合 设计用例,
为保证接口的独立性,避免依赖环境的数据造成用例的运行失败,在用例里面 除了新建接口 其余的接口里面要先调用新建接口,创建对象 在该对象基础上验证接口,避免测试数据过多,在每个测试用例执行完成时 销毁创建的测试数据
1)逻辑业务,主要指的是一些逻辑业务依赖关系(比如抓拍 依赖于 有开启的设备)
2)异常测试:参数异常(key):关键字参数(应用其他的关键字替换进行测试)、参数为空、参数多少(通过添加参数增添个数),参数错误。
数据异常(value):关键字数据(填入的数据用其他的数据语言的数据替用)、数据长度、数据为空、数据错误。
7-pytest的应用
1)@pytest.mark.skip(reason="") 跳过用例
2)@pytest.mark.parametrize() 测试数据参数化
3)import openapi_client
def test_get_tracks_trackid_crop_fail(self, Client):
'''
获取的trackid不存在 返回状态码为500
:param Client:
:param host:
:return:
'''
try:
response=Client.passers_api.get_track_crop(track_id="track_id")
except openapi_client.exceptions.ApiException as e:
assert_that(str(e)).contains("500")
assert_that(str(e)).contains("unexpected error")
4)conftest文件的应用
创建资源 使用后自动销毁 在创建的创建资源的方法下面添加 def fin():
样例:
@pytest.fixture(scope="function")
def post_import_face(request):
class PostImportFace(object):
def post_import_face(self):
url=""
data={}
headers['Content-Type'] = multipart_encoder.content_type
response = requests.post(url=url, data=multipart_encoder, headers=headers, verify=False)
face_id = response.text
def fin():
url = ""
headers = {}
requests.delete(url, headers=headers)
request.addfinalizer(fin)
return face_id
return PostImportFace()
``
OpenAPI.json 文件修改:
1.替换 /v1/ 为 /ctbox/v/
2./ctbox/v1/devices 创建设备 返回 去掉 “format”: “binary”,
3./ctbox/v1/tracks/{trackId}/crop “text/plain” 替换为 “/”
4./ctbox/v1/tracks/{trackId}/scene “text/plain” 替换为 "/"
5.只有返回状态的 OpenAPI.json 文档中的responses去掉
"format": “binary”,
“default”: "ok"