三十六、实战演练之接口自动化平台的测试步骤管理接口设计
创始人
2025-06-01 19:59:08

一、 测试步骤创建

接口名称: /test_steps/

请求方式: POST

参数格式: JSON

请求参数:

参数

变量名

类型

说明

是否必传

用例名称

name

字符串

任务名称

接口id

interface

整数

所属项目id

请求头

headers

json

包含模块的id数组

请求参数

request

json

请求体参数

上传文件参数

file

json

上传文件参数

前置脚本

setup_script

字符串

前置执行脚本

后置脚本

teardown_script

字符串

后置执行脚本

请求示例:

json格式参数

{"title": "登录成功","headers": {},"request": {}, "file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","interface": 1 	}

返回示例

响应状态码:201

响应数据:

{"id": 1,"title": "登录成功","headers": {},"request": {}, 	"file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据 \n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","interface": 1 
}

二、 删除测试步骤

接口名称: /test_steps/id/

请求方式: DELETE

参数格式: 路径参数

请求参数:

返回示例

响应状态码:204

响应数据:无

三、修改测试步骤

接口名称: /test_steps/id/

请求方式: PUT/PATCH

参数格式: JSON

请求参数:

参数

变量名

类型

说明

是否必传

用例名称

name

字符串

任务名称

put请求必传

接口id

interface

整数

所属项目id

put请求必传

请求头

headers

json

包含模块的id数组

请求参数

request

json

请求体参数

上传文件参数

file

json

上传文件参数

前置脚本

setup_script

字符串

前置执行脚本

后置脚本

teardown_script

字符串

后置执行脚本

请求示例:

json格式参数

{"title": "登录成功","headers": {},"request": {}, "file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","interface": 1 	}

返回示例

响应状态码:200 响应数据:

{"id": 1,"title": "登录成功","headers": {},"request": {}, 	"file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据 \n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","interface": 1 
}

四、查看测试步骤列表

接口名称: /test_steps/

请求方式: GET

参数格式:

请求参数:

参数

变量名

类型

说明

是否必传

测试场景

scene

整数

测试场景id

接口

interface

整数

接口id

返回示例

响应状态码:200

响应数据:

[{"id": 1,"title": "登录成功","headers": {},"request": {},"file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据 \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据 \n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","interface": 1}
]

五、查看测试步骤

接口名称: /test_steps/id/

请求方式: GET

参数格式: 路径参数

请求参数:

返回示例

响应状态码:200

响应数据:

{"id": 1,"interface": { 		"id": 1,"steps": [{"id": 1,"title": "登录成功" }],"name": "登录","url": "/users/login/","method": "POST","type": "1","project": 1 	},"title": "登录成功","headers": {},"request": {}, 	"file": [],"setup_script": "# 前置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据\n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n","teardown_script": "# 后置脚本(python):\n# global_tools:全局工具函数\n# data:用例数据 \n# response:响应对象response \n# env: 局部环境\n# ENV: 全局环境\n# db: 数据库操作对象\n"
}

六、 后端代码

1. 序列化器

在testcases应用中创建serializers.py 模块,编写代码如下:

from projects.serializers import InterfaceSerializer
from .models import TestStep, UploadFile, TestScene, SceneData
from rest_framework.serializers import ModelSerializerclass TestStepSerializer(ModelSerializer):"""测试步骤序列化器"""class Meta:model = TestStep fields = ' all 'class TestStepRetrieveSerializer(ModelSerializer):"""测试步骤详情序列化器"""interface = InterfaceSerializer()class Meta:model = TestStep fields = ' all '

测试步骤详情中需要展示接口信息,所以单独创建一个序列化器用来序列化测试步骤详情。

或者直接在测试步骤序列化器中加个depth =1。但是这样子会把新建测试用例选择接口的时候,接口这个字段没有了,因为变成只读的了。

2. 过滤器

可以直接在filterset_fields = ['interface']通过接口去过滤,那怎么通过测试场景去过滤呢?直接在filterset_fields加个可以吗,显示是不行的,因为TestStep模型中压根就没有这个字段。

那该怎么办? TestStep模型和TestScene模型(测试用例和测试场景是多对多),我们可以通过中间表SceneData去查询。

比如说我想查scene_id=1的这个场景下所有的测试用例,那这个我们该怎么写呢?

我们先进入shell

In [4]: from testplans.models import *In [5]: queryset = TestStep.objects.filter(scenedata__scene=1)In [6]: print(queryset)
In [7]: print(queryset.query)
SELECT `tb_test_step`.`id`, `tb_test_step`.`title`, `tb_test_step`.`interface_id`, `tb_test_step`.`headers`, `tb_test_step`.`request`, `tb_test_step`.`file`, `tb_test_step`.`setup_script`, `tb_test_step`.`teardown_script` FROM `tb_test_step` INNER JOIN `tb_scene_data` ON (`tb_test_step`.`id` = `tb_scene_data`.`step_id`) WHERE `tb_scene_data`.`scene_id` = 1In [8]: 

 所以如果我这样子配也是可以的,但是不美观,我们还可以有其他的办法。

 那就是复写过滤器。

在testplans/filters.py 中定义如下过滤器:

from .models import TestStep
from django_filters import rest_framework as filtersclass StepFilterSet(filters.FilterSet):"""测试步骤过滤器"""scene = filters.NumberFilter(field_name='scenedata scene')class Meta:model = TestStepfields = ['scene', 'interface']

然后在视图里添加 filterset_class = TestStepFilter

3. 视图

复写 get_serializer_class方法,实现不同的操作使用不同的序列化器 。

我们看下父类的 get_serializer_class方法,也是直接返回一个序列化器对象。

self.action是啥?当我们是查询数据集的时候,action就是list;当我们是创建的时候,action就是create;当我们是修改数据的时候,action就是update或者是partial_update;当我们删除的时候,他就是destroy。当我们去查看某一个的数据的时候,那他就是retrieve。

所以我们可以根据action这个属性是什么去返回不同的序列化器。

class TestStepViewSet(ModelViewSet): """测试步骤视图集"""queryset = TestStep.objects.all() serializer_class = TestStepSerializer permission_classes = [IsAuthenticated]filterset_class = StepFilterSet# 方法1def get_serializer_class(self): if self.action == 'retrieve':return TestStepRetrieveSerializerreturn super().get_serializer_class()# 方法二def get_serializer_class(self):if self.action == 'retrieve':return TestStepRetrieveSerializerreturn self.serializer_class

4. 路由

from rest_framework.routers import DefaultRouter
from . import viewsroute = DefaultRouter() 
route.register('test_steps', views.TestStepViewSet)urlpatterns = route.urls

相关内容

热门资讯

网上说的sm是啥意思,sm指的... 网上说的sm是啥意思目录什么是SM?sm指的什么分别指的什么 什么是SM?SM是指“性施虐癖”(S)...
怎么查自己电脑宽带的余额,联通... 怎么查自己电脑宽带的余额目录怎么查自己电脑宽带的余额联通怎么查宽带余额?怎么查电脑宽带里剩下多少钱如...
什么叫潮汐和潮汐能 极速百科网... 什么叫潮汐和潮汐能目录什么叫潮汐和潮汐能什么叫潮汐和潮汐能潮汐能是什么?什么叫潮汐和潮汐能什么叫潮汐...
借呗额度为什么会降低,支付宝借... 借呗额度为什么会降低目录借呗额度为什么会降低支付宝借呗降额原因有哪些蚂蚁借呗额度怎么降低了 蚂蚁借呗...
河南豫剧边玉洁多大了,河南豫剧... 河南豫剧边玉洁多大了目录河南豫剧边玉洁多大了河南豫剧边玉洁多大了(河南豫剧边玉洁的老公)边玉洁的介绍...
大轮毂薄胎和小轮毂厚胎哪个比较... 今天给各位分享大轮毂薄胎和小轮毂厚胎哪个比较好?总结一下它们各自...的知识,其中也会对汽车轮毂大轮...
北奔汽车怎么样(北奔属于哪个集... 今天给各位分享北奔汽车怎么样的知识,其中也会对北奔属于哪个集团进行解释,如果能碰巧解决你现在面临的问...
世界全部山脉高度排名,世界十大... 世界全部山脉高度排名目录世界全部山脉高度排名世界十大山脉排名世界前三的高的山脉分别是什么?世界十大山...
蚺怎么读(红尾蚺怎么读) 蚺怎... 本篇文章极速百科给大家谈谈蚺怎么读,以及红尾蚺怎么读对应的知识点,希望对各位有所帮助,不要忘了收藏本...
车载清洗汽车机好用吗(汽车清洗... 本篇文章极速百科给大家谈谈车载清洗汽车机好用吗,以及汽车清洗机器对汽车有好处吗对应的知识点,希望对各...
锐志2.5v马力多少匹?(锐志... 今天给各位分享锐志2.5v马力多少匹?的知识,其中也会对锐志25功率进行解释,如果能碰巧解决你现在面...
...列车时刻表查询,从大理到... 今天给各位分享...列车时刻表查询,从大理到丽江高铁火车最新消息的知识,其中也会对大理到丽江的高铁票...
天赋异禀什么意思,天生异禀是什... 天赋异禀什么意思目录天赋异禀什么意思天生异禀是什么意思天赋异禀是什么意思?天赋异禀是什么意思?禀字拼...
个人宣言简短,个人宣言简短有哪... 个人宣言简短目录个人宣言简短个人宣言简短有哪些?有什么可以作为座右铭,简洁有力的句子,用以激励自己求...
关于叶圣陶的资料(关于叶圣陶的... 本篇文章极速百科给大家谈谈关于叶圣陶的资料,以及关于叶圣陶的资料了解到了什么对应的知识点,希望对各位...
国徽的由来和象征意义(国徽的由... 今天给各位分享国徽的由来和象征意义的知识,其中也会对国徽的由来和象征意义100字进行解释,如果能碰巧...
夜天子第二季什么时候播,夜天子... 夜天子第二季什么时候播目录夜天子第二季什么时候播夜天子第二部什么时候播出CLANNAD的第二季什么时...
玄武岛怎么去,天龙玄武岛镜怎么... 玄武岛怎么去目录玄武岛怎么去天龙玄武岛镜怎么去天龙八部里的玄武岛到怎么走天龙八部里面的玄武岛,即圣兽...
绝世武神修为分为哪几个境界,绝... 绝世武神修为分为哪几个境界目录绝世武神修为分为哪几个境界绝世武神修为分为哪几个境界 绝世武神修为境界...
下线车是什么意思(下线车是什么... 今天给各位分享下线车是什么意思的知识,其中也会对下线车是什么意思可以买吗进行解释,如果能碰巧解决你现...
如何用usb连接音响,笔记本如... 如何用usb连接音响目录如何用usb连接音响笔记本如何连外置音箱?电脑音响怎么连接到电脑上?如何用u...
怎么在qq上设置密码锁,如何设... 怎么在qq上设置密码锁目录怎么在qq上设置密码锁如何设置qq密码锁怎么在登QQ设置密码怎样给QQ设置...
1英镑等于多少人民币,1英镑多... 1英镑等于多少人民币目录1英镑等于多少人民币1英镑多少人民币一英镑等于多少人民币100英镑等于多少人...
织围巾怎么收针(织围巾怎么收针... 本篇文章极速百科给大家谈谈织围巾怎么收针,以及织围巾怎么收针教程对应的知识点,希望对各位有所帮助,不...
2023中国国际商用车展(武汉... 本篇文章极速百科给大家谈谈2023中国国际商用车展(武汉车展)展览会时间表,以及武汉商用车展延期对应...
新鲜羊睪丸怎么做好吃,新鲜羊睪... 新鲜羊睪丸怎么做好吃目录吃羊睾丸害处 吃羊睾丸的功效作用新鲜羊睪丸怎么做好吃?羊睾丸叫什么菜名 吃羊...
重庆大学弘深学院如何,重庆大学... 重庆大学弘深学院如何目录重庆大学弘深学院如何重庆大学弘深班计算机怎么样通过本科评估的三本学校会怎么样...
标准正态分布表怎么使用,标准正... 标准正态分布表怎么使用目录标准正态分布表怎么使用标准正态分布表是如何使用的?请问:标准正态分布表的使...
斯巴鲁翼豹sti是后驱吗(斯巴... 本篇文章极速百科给大家谈谈斯巴鲁翼豹sti是后驱吗,以及斯巴鲁翼豹wrc对应的知识点,希望对各位有所...
矩阵的2次方怎么求,三阶矩阵的... 矩阵的2次方怎么求目录矩阵的2次方怎么求三阶矩阵的2次方怎么求题对2求一个矩阵次方怎么运算?如何计算...