django-14-测试步骤执行接口

一、接口设计

接口名称:/test_steps/run/

请求方式: POST 

参数格式: JSON 

请求参数: 

1696465382901-89d4e287-6e1b-442d-832e-9b80715b712e.png

请求示例: json格式参数

{
 "data": {
     "id": 2,
     "interface": {
         "url": "/users/login/",
         "method": "POST"

     },
     "title": "登录失败",
     "headers": {},
     "request": {
         "json": {
             "username": "xinlan",
             "password": "123123"

         },
         "params": {}
     },
     "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"

 },
 "env": 1

}

返回示例:

  • 响应状态码:200 
  • 响应数据:
{
	"name": "登录失败",
	"log_data": [
			["INFO", "【INFO】 |   开始执行用例:【登录失败】\n"],
			["DEBUG", "临时变量:\n{}"],
			["DEBUG", "全局变量:\n{'host': 'http://127.0.0.1:8080', 
				'headers': {
					'customer-header': 'wahaha'
				}, 'key1': 'value1', 'key2': 'value2'
			}
			"], ["INFO", "【INFO】 |   *********执行前置脚本*********"],
			["INFO", "【INFO】 |   发送

				[POST] 请求: 请求地址为http: //127.0.0.1:8080/users/login/:"],["DEBUG","请求头:

				\n {
					'User-Agent': 'python-requests/2.28.1',
					'Accept-Encoding': 'gzip, deflate',
					'Accept': '*/*',
					'Connection': 'keep-alive',
					'customer-header': 'wahaha',
					'Content-Length': '44',
					'Content-Type': 'application/json'
				}
				"],["
				DEBUG ","
				请求体:

				\ n {\
					n\ "username\": \"xinlan\",\n \"password\": \"123123\"\n}"],
				["INFO", "【INFO】 |   请求响应状态码:401"],
				["DEBUG", "响应头:\n{'Date': 'Thu, 21 Jul 
					2022 12: 42: 41 GMT ', '
					Server ': '
					WSGIServer / 0.2 CPython / 3.8 .5 ', '
					Content - Type ': 
					'application/json', 'WWW-Authenticate': 'Bearer realm=\"api\"', 'Vary': 'Accept, 
					Origin ', '
					Allow ': '
					POST, OPTIONS ', '
					X - Frame - Options ': '
					DENY ', '
					Content - Length ': 
					'37', 'X-Content-Type-Options': 'nosniff', 'Referrer-Policy': 'same-origin'
				}
				"], ["DEBUG", "响应体:\n{\n \"detail\": \"用户名密码错误!\"\n}"],
				["INFO", "【INFO】 |    **
					** ** ** * 执行后置脚本 ** ** ** ** * "],["
					INFO ","【
					INFO】 |  登录失败执行—— > 【通过】

					\ n "]],"
					url ":"
					http: //127.0.0.1:8080/users/login/","method":"POST","status_cede":40
					1, "response_header": {
						"Date": "Thu, 21 Jul 2022 12:42:41 
						GMT ","
						Server ":"
						WSGIServer / 0.2 CPython / 3.8 .5 ","
						ContentType ":"
						application / json ","
						WWW - Authenticate ":"
						Bearer

						realm = \"api\"",
						"Vary": "Accept, Origin",
						"Allow": "POST, OPTIONS",
						"X-FrameOptions": "DENY",
						"Content-Length": "37",
						"X-Content-TypeOptions": "nosniff",
						"Referrer-Policy": "same-origin"
					}, "requests_header": {
						"UserAgent": "python-requests/2.28.1",
						"Accept-Encoding": "gzip,

						deflate ","
						Accept ":" *
						/*","Connection":"keep-alive","customerheader":"wahaha","Content-Length":"44","ContentType":"application/json"},"response_body":"{\n
						\"detail\": \"用户名密码错误!

						\"\n}","requests_body":"{\n \"username\": \"xinlan\",\n \"password\": 
						\"123123\"\n}","state":"成功","run_time":"0.345s"}

二、后端代码

创建 testplans/tasks.py 模块,然后编写如下代码:


from projects.models import TestEnv
from testplans.models import TestScene, TestPlan
# from testplans.serializers import TestSceneRunSerializer, TestPlanRunSerializer
# from reports.models import Report, Record

from apitestengine.core.cases import run_test


def _get_env_config(env, debug=True):
    """
    获取测试环境的配置数据
    :param env: 测试环境对象
    :param debug: 是否是调试模式
    :return:
    """
    # 获取环境变量
    var = {**env.global_variable, **env.debug_global_variable} if debug else env.global_variable

    ENV = {
        **var,
        'host': env.host,
        'headers': env.headers
    }
    return {
        'ENV': ENV,
        'DB': env.db,
        'global_func': env.global_func
    }


def run_case(case, env_id):
    """执行单条用例"""
    # 1. 获取环境数据
    env = TestEnv.objects.get(pk=env_id)
    config = _get_env_config(env, debug=True)
    # 2. 执行用例
    res, debug_var = run_test(case_data=[{'Cases': [case]}], env_config=config, debug=True)
    # 3. 构造返回结果
    result = res['results'][0]['cases'][0]

    # 保存一下debug模式下的环境变量
    env.debug_global_variable = debug_var
    env.save()

    return result


# def run_scene(pk, env_id):
#     """执行单个的测试场景"""
#     # 1. 获取环境配置
#     env = TestEnv.objects.get(id=env_id)
#     config = _get_env_config(env, debug=True)
#     # 2. 构造测试数据
#     scene = TestScene.objects.get(id=pk)
#     cases = TestSceneRunSerializer(scene).data['scenedata_set']
#     # 套件内的用例要排序
#     cases.sort(key=lambda x:x['sort'])
#     # 组装用例数据
#     scene_data = {'Cases': [item['step'] for item in cases], 'name': scene.name}
#     # 3. 运行测试用例
#     res, debug_var = run_test(case_data=[scene_data], env_config=config, debug=True)
#     # 4. 保存一下调试变量
#     env.debug_global_variable = debug_var
#     env.save()
#     # 5. 返回结果
#     result = res['results'][0]
#     return result


# def run_plan(pk, env_id, record_id):
#     """同步执行测试计划"""
#     # 1. 获取环境配置
#     env = TestEnv.objects.get(id=env_id)
#     config = _get_env_config(env, debug=True)
#     # 2. 构造测试数据
#     # 读取计划任务数据
#     plan = TestPlan.objects.get(pk=pk)
#     task_data = TestPlanRunSerializer(plan).data
#     scene_list = []
#     for scene in task_data['scenes']:
#         cases = scene['scenedata_set']
#         # 排序
#         cases.sort(key=lambda x: x['sort'])
#         scene_list.append({'Cases': [item['step'] for item in cases], 'name': scene['name']})
#     # 3. 运行测试用例
#     res = run_test(case_data=scene_list, env_config=config, debug=False)
#     # 4. 保存结果
#     # 更新测试记录
#     record = Record.objects.get(id=record_id)
#
#     res['plan'] = plan.id
#     res['test_env'] = env_id
#     res['tester'] = record.tester
#
#     # 保存报告
#     Report.objects.create(info=res, record=record)
#
#     # 更新record的数据
#     record.all = res.get('all', 0)
#     record.success = res.get('success', 0)
#     record.fail = res.get('fail', 0)
#     record.error = res.get('error', 0)
#     record.pass_rate = f"{res.get('success', 0) / res.get('all'):.2f}" if res.get('all', 0) else '0'
#     # record.pass_rate = ':.2f'.format(res.get('success', 0) / res.get('all')) if res.get('all', 0) else '0'
#     record.status = '执行完毕'
#     record.save()




视图:

class TestStepViewSet(ModelViewSet):
    queryset = TestStep.objects.all()
    serializer_class = TestStepSerializer

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return TestStepRetrieveSerializer
        return super().get_serializer_class()

    @action(methods=['post'], detail=False)
    def run(self, request, *args, **kwargs):
        # 1. 获取测试数据
    
        cases = request.data.get('data')
        env_id = request.data.get('env')
        if not env_id:
            return Response({'msg': '请求参数env必填', 'data': None}, status=400)
        try:
            TestEnv.objects.get(id=env_id)
        except:
            return Response({'msg': '参数env传入的为无效值', 'data': None}, status=400)
        res = run_case(cases=cases, env_id=env_id)
        return Response(res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值