Django实现接口自动化平台(十四)测试用例模块Testcases序列化器及视图【持续更新中】

相关文章:

Django实现接口自动化平台(十三)接口模块Interfaces序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客

本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看:

python django vue httprunner 实现接口自动化平台(最终版)_python+vue自动化测试平台_做测试的喵酱的博客-CSDN博客

一、Testcases应用及相关接口

|--------|----------------------|-------------------|-------------------|
| 请求方式 | URI | 对应action | 实现功能 |
| GET | /testcases/ | .list() | 查询testcase列表 |
| POST | /testcases/ | .create() | 创建一条数据 |
| GET | /testcases/{id}/ | .retrieve() | 检索一条testcase的详细数据 |
| PUT | /testcases/{id}/ | update() | 更新一条数据中的全部字段 |
| PATCH | /testcases/{id}/ | .partial_update() | 更新一条数据中的部分字段 |
| DELETE | /testcases/{id}/ | .destroy() | 删除一条数据 |
| POST | /testcases/{id}/run/ | | 运行某个接口下的所有case |

1.1 用例列表

|-----|-------------|---------|--------------|
| GET | /testcases/ | .list() | 查询testcase列表 |

1.2 创建用例

1.2.1 基本信息

1、拉取了项目列表

2、拉取了项目下的接口列表

3、前置用例列表

4、拉取了所有的配置列表

1.2.2 基本信息

二、模型类

python 复制代码
from django.db import models

from utils.base_models import BaseModel


class Interfaces(BaseModel):
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
    name = models.CharField('接口名称', max_length=200, unique=True, help_text='接口名称')
    project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
                                related_name='interfaces', help_text='所属项目')
    tester = models.CharField('测试人员', max_length=50, help_text='测试人员')
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, help_text='简要描述')

    class Meta:
        db_table = 'tb_interfaces'
        verbose_name = '接口信息'
        verbose_name_plural = verbose_name
        ordering = ('id',)

    def __str__(self):
        return self.name

这段代码定义了一个名为Testcases的Django模型类,继承了BaseModel。

首先,通过from django.db import models导入了Django的models模块和自定义的BaseModel模块。

然后,定义了Testcases模型类,它包含了以下字段:

  • id:主键字段,使用AutoField类型生成自增的id。
  • name:用例名称字段,使用CharField类型,最大长度为50,设置为唯一值。
  • interface:外键字段,关联到interfaces.Interfaces模型,表示该用例所属的接口。
  • include:前置字段,使用TextField类型,允许为空,保存用例执行前需要执行的顺序信息。
  • author:编写人员字段,使用CharField类型,最大长度为50,保存编写该用例的人员信息。
  • request:请求信息字段,使用TextField类型,保存请求的详细信息。

接下来,定义了该模型类的Meta类,包含了一些元数据:

  • db_table:数据库表的名称,设置为tb_testcases。
  • verbose_name:该模型的可读名称,设置为'用例信息'。
  • verbose_name_plural:该模型的复数形式名称,与verbose_name相同。
  • ordering:查询结果的默认排序规则,按照id字段进行升序排序。

最后,定义了__str__方法,返回用例的名称,用于在后台管理界面和其他地方显示该模型对象的可读信息。

通过以上定义,您可以使用Django框架创建一个名为Testcases的数据表,其中包含了上述定义的字段,并且可以进行数据操作和查询。

注意:

所有请求相关的信息,如header、URI、请求体、断言等等,全部在模型类 request字段中

request的值,是一个json字符串。如:

python 复制代码
{
	"test": {
		"name": "1陈帅百度",
		"request": {
			"url": "/mcp/pc/pcsearch",
			"method": "POST",
			"json": {
				"invoke_info": {
					"pos_1": [{}],
					"pos_2": [{}],
					"pos_3": [{}]
				}
			}
		},
		"validate": [{
			"check": "status_code",
			"expected": 200,
			"comparator": "equals"
		}]
	}
}

包含了请求与断言的信息。

底层使用的httprunner 1.0 做的接口自动化驱动,case的形式,就是json格式的。

相关资料:

httprunner 2.x的基本使用(二)_做测试的喵酱的博客-CSDN博客

三、序列化器类

python 复制代码
class TestcaseModelSerializer(serializers.ModelSerializer):
    interface = InterfaceProjectModelSerializer(label='所属项目和接口信息', help_text='所属项目和接口信息')

    class Meta:
        model = Testcases
        exclude = ('create_datetime', 'update_datetime')
        extra_kwargs = {
            'request': {
                'write_only': True
            },
            'include': {
                'write_only': True
            },
        }

    # def validate_request(self, attr):
    #     # TODO
    #     return attr
    #
    # def validate(self, attrs):
    #     # TODO
    #     return attrs

    def to_internal_value(self, data):
        result = super().to_internal_value(data)
        iid = data.get('interface').get('iid')
        result['interface'] = Interfaces.objects.get(id=iid)
        return result

    # def create(self, validated_data):
    #     pass


# class TestcaseRunSerializer(serializers.ModelSerializer):
#     env_id = serializers.IntegerField(label="所属环境id", help_text="所属环境id",
#                                       validators=[ManualValidateIsExist('env')])
#
#     class Meta:
#         model = Testcases
#         fields = ('id', 'env_id')

class TestcaseRunSerializer(RunSerializer):

    class Meta(RunSerializer.Meta):
        model = Testcases

四、视图

python 复制代码
import json
import os
from datetime import datetime

from django.conf import settings
from django.http import JsonResponse
from rest_framework import viewsets
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.decorators import action

from .models import Testcases
from envs.models import Envs
from . import serializers
from utils import handle_datas, common
from utils.mixins import RunMixin


class TestcasesViewSet(RunMixin, viewsets.ModelViewSet):

    queryset = Testcases.objects.all()
    serializer_class = serializers.TestcaseModelSerializer
    permission_classes = [permissions.IsAuthenticated]

    # 删除
    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        response.status_code = 200
        response = {"code":2000,"msg":"删除成功"}
        response =JsonResponse(response)
        return response

    # 获取单个详情
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object() # type: Testcases
        try:
            testcase_include = json.loads(instance.include, encoding='utf-8')
        except Exception:
            testcase_include = dict()

        try:
            testcase_request = json.loads(instance.request, encoding='utf-8')
        except Exception:
            return Response({'msg': '用例格式有误', 'status': 400}, status=400)

        testcase_request_data = testcase_request.get('test').get('request')
        # 获取json参数
        json_data = testcase_request_data.get('json')
        json_data_str = json.dumps(json_data, ensure_ascii=False)

        # 获取extract参数
        extract_data = testcase_request.get('test').get('extract')
        extract_data = handle_datas.handle_data3(extract_data)

        # 获取validate参数
        validate_data = testcase_request.get('test').get('validate')
        validate_data = handle_datas.handle_data1(validate_data)

        # 获取variables参数
        variables_data = testcase_request.get('test').get('variables')
        variables_data = handle_datas.handle_data2(variables_data)

        # 获取parameters参数
        parameters_data = testcase_request.get('test').get('parameters')
        parameters_data = handle_datas.handle_data3(parameters_data)

        # 获取setup_hooks参数
        setup_hooks_data = testcase_request.get('test').get('setup_hooks')
        setup_hooks_data = handle_datas.handle_data5(setup_hooks_data)

        # 获取teardown_hooks参数
        teardown_hooks_data = testcase_request.get('test').get('teardown_hooks')
        teardown_hooks_data = handle_datas.handle_data5(teardown_hooks_data)

        data = {
            "author": instance.author,
            "testcase_name": instance.name,
            "selected_configure_id": testcase_include.get('config'),
            "selected_interface_id": instance.interface_id,
            "selected_project_id": instance.interface.project_id,
            "selected_testcase_id": testcase_include.get('testcases', []),
            "method": testcase_request_data.get('method'),
            "url": testcase_request_data.get('url'),
            "param": handle_datas.handle_data4(testcase_request_data.get('params')),
            "header": handle_datas.handle_data4(testcase_request_data.get('headers')),
            "variable": handle_datas.handle_data2(testcase_request_data.get('data')),
            "jsonVariable": json_data_str,
            "extract": extract_data,
            "validate": validate_data,
            # 用例的当前配置(variables)
            "globalVar": variables_data,
            "parameterized": parameters_data,
            "setupHooks": setup_hooks_data,
            "teardownHooks":teardown_hooks_data
        }

        return Response(data, status=200)

    # @action(methods=['post'], detail=True)
    # def run(self, request, *args, **kwargs):
    #     # 1、取出用例模型对象并获取env_id
    #     # instance = self.get_object()    # type: Testcases
    #     # serializer = self.get_serializer(data=request.data)
    #     # serializer.is_valid(raise_exception=True)
    #     # env_id = serializer.validated_data.get('env_id')
    #     # env = Envs.objects.get(id=env_id)
    #
    #     # 2、创建以时间戳命名的目录
    #     # dirname = datetime.strftime(datetime.now(), "%Y%m%d%H%M%S")
    #     # testcase_dir_path = os.path.join(settings.PROJECT_DIR, datetime.strftime(datetime.now(), "%Y%m%d%H%M%S"))
    #     # os.makedirs(testcase_dir_path)
    #
    #     # 3、创建以项目名命名的目录
    #     # 4、生成debugtalks.py、yaml用例文件
    #     # common.generate_testcase_file(instance, env, testcase_dir_path)
    #
    #     # 5、运行用例并生成测试报告
    #     # return common.run_testcase(instance, testcase_dir_path)
    #     qs = [self.get_object()]
    #     return self.execute(qs)

    def get_serializer_class(self):
        if self.action == "run":
            return serializers.TestcaseRunSerializer
        else:
            return super().get_serializer_class()

    def get_testcase_qs(self):
        return [self.get_object()]
        # return self.queryset.filter(id=self.get_object().id)

这段代码是一个Django视图集,用于处理测试用例的增删改查操作。它继承了RunMixin类,并且使用了ModelViewSet视图集来简化代码。

该视图集定义了以下几个方法:

  1. destroy: 重写了父类的destroy方法,删除指定的测试用例,并返回一个删除成功的响应。
  2. retrieve: 重写了父类的retrieve方法,获取单个测试用例的详情,并将相关数据进行处理后返回。
  3. get_serializer_class: 根据请求的动作不同,选择不同的序列化器进行序列化。
  4. get_testcase_qs: 获取测试用例的查询集。

除此之外,还有一段被注释掉的代码,它包含了运行测试用例的逻辑,根据时间戳创建目录、生成测试用例文件,并运行测试用例生成测试报告。

需要注意的是,这段代码中使用了一些自定义的工具类和函数,如handle_datas、common等,未提供相关代码,可能需要根据实际情况自行补充。

相关推荐
noravinsc8 分钟前
人大金仓数据库 与django结合
数据库·python·django
豌豆花下猫15 分钟前
Python 潮流周刊#102:微软裁员 Faster CPython 团队(摘要)
后端·python·ai
sy_cora21 分钟前
IEEE 列表会议第五届机器人、自动化与智能控制国际会议
运维·人工智能·机器人·自动化
yzx9910131 小时前
Gensim 是一个专为 Python 设计的开源库
开发语言·python·开源
麻雀无能为力1 小时前
python自学笔记2 数据类型
开发语言·笔记·python
Ndmzi1 小时前
matlab与python问题解析
python·matlab
懒大王爱吃狼1 小时前
怎么使用python进行PostgreSQL 数据库连接?
数据库·python·postgresql
猫猫村晨总1 小时前
网络爬虫学习之httpx的使用
爬虫·python·httpx
web150854159351 小时前
Python线性回归:从理论到实践的完整指南
python·机器学习·线性回归
ayiya_Oese1 小时前
[训练和优化] 3. 模型优化
人工智能·python·深度学习·神经网络·机器学习