欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

测试开发进阶(三十四)

程序员文章站 2024-03-21 23:53:40
...

数据库模型图

测试开发进阶(三十四)

创建app

根据上面的数据库设计,创建9个app

  • configures

  • debugtalks

  • envs

  • interfaces

  • projects

  • reports

  • testsuits

  • testcases

  • user

完成注册

import sys	
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))	
INSTALLED_APPS = [	
    'django.contrib.admin',	
    'django.contrib.auth',	
    'django.contrib.contenttypes',	
    'django.contrib.sessions',	
    'django.contrib.messages',	
    'django.contrib.staticfiles',	
    'rest_framework',	
    'corsheaders',	
    'configures.apps.ConfiguresConfig',	
    'debugtalks.apps.DebugtalksConfig',	
    'envs.apps.EnvsConfig',	
    'interfaces.apps.InterfacesConfig',	
    'projects.apps.ProjectsConfig',	
    'reports.apps.ReportsConfig',	
    'testsuits.apps.TestsuitsConfig',	
    'testcases.apps.TestcasesConfig',	
    'user.apps.UserConfig',	
]

测试开发进阶(三十四)

抽象数据库基类

从数据库模型图可以看出,有很多部分都重复了

  • create_time

  • update_time

  • is_delete

from django.db import models	
class BaseModel(models.Model):	
    """	
    数据库表公共字段	
    """	
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间", help_text="创建时间")	
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间", help_text="更新时间")	
    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除", help_text="逻辑删除")	
    class Meta:	
        # 为抽象模型类, 用于其他模型来继承,数据库迁移时不会创建BaseModel表	
        abstract = True	
        verbose_name = "公共字段表"	
        db_table = 'BaseModel'

default=False默认情况下不删除

各模块的模型

configures

# configures.models.Configures	
from django.db import models	
from utils.base_models import BaseModel	
class Configures(BaseModel):	
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')	
    name = models.CharField('配置名称', max_length=50, help_text='配置名称')	
    interface = models.ForeignKey('interfaces.Interfaces',	
                                  on_delete=models.CASCADE,	
                                  related_name='configures',	
                                  help_text='所属接口')	
    author = models.CharField('编写人员', max_length=50, help_text='编写人员')	
    request = models.TextField('请求信息', help_text='请求信息')	
    class Meta:	
        db_table = 'tb_configures'	
        verbose_name = '配置信息'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

debugtalks

# debugtalks.models.DebugTalks	
from django.db import models	
from utils.base_models import BaseModel	
class DebugTalks(BaseModel):	
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')	
    name = models.CharField('debugtalk文件名称', max_length=200, default='debugtalk.py', help_text='debugtalk文件名称')	
    debugtalk = models.TextField(null=True, default='#debugtalk.py', help_text='debugtalk.py文件')	
    project = models.OneToOneField('projects.Projects', on_delete=models.CASCADE,	
                                   related_name='debugtalks', help_text='所属项目')	
    class Meta:	
        db_table = 'tb_debugtalks'	
        verbose_name = 'debugtalk.py文件'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

interfaces

# interfaces.models.Interfaces	
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	
    def __str__(self):	
        return self.name

projects

# projects.models.Projects	
from django.db import models	
from utils.base_models import BaseModel	
class Projects(BaseModel):	
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')	
    name = models.CharField('项目名称', max_length=200, unique=True, help_text='项目名称')	
    leader = models.CharField('负责人', max_length=50, help_text='项目负责人')	
    tester = models.CharField('测试人员', max_length=50, help_text='项目测试人员')	
    programmer = models.CharField('开发人员', max_length=50, help_text='开发人员')	
    publish_app = models.CharField('发布应用', max_length=100, help_text='发布应用')	
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, default='', help_text='简要描述')	
    class Meta:	
        db_table = 'tb_projects'	
        verbose_name = '项目信息'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

reports

# reports.models.Reports	
from django.db import models	
from utils.base_models import BaseModel	
class Reports(BaseModel):	
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')	
    name = models.CharField('报告名称', max_length=200, unique=True, help_text='报告名称')	
    result = models.BooleanField('执行结果', default=1, help_text='执行结果')   # 1为成功, 0为失败	
    count = models.IntegerField('用例总数', help_text='总用例数')	
    success = models.IntegerField('成功总数', help_text='成功总数')	
    html = models.TextField('报告HTML源码', help_text='报告HTML源码', null=True, blank=True, default='')	
    summary = models.TextField('报告详情', help_text='报告详情', null=True, blank=True, default='')	
    class Meta:	
        db_table = 'tb_reports'	
        verbose_name = '测试报告'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

testcases

# testcases.models.Testcases	
from django.db import models	
from utils.base_models import BaseModel	
class Testcases(BaseModel):	
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')	
    name = models.CharField('用例名称', max_length=50, unique=True, help_text='用例名称')	
    interface = models.ForeignKey('interfaces.Interfaces', on_delete=models.CASCADE,	
                                  help_text='所属接口')	
    # include = models.ForeignKey('', on_delete=models.SET_NULL, null=True, related_name='testcases')	
    include = models.TextField('前置', null=True, help_text='用例执行前置顺序')	
    author = models.CharField('编写人员', max_length=50, help_text='编写人员')	
    request = models.TextField('请求信息', help_text='请求信息')	
    class Meta:	
        db_table = 'tb_testcases'	
        verbose_name = '用例信息'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

testsuits

# testsuits.models.Testsuits	
from django.db import models	
from utils.base_models import BaseModel	
class Testsuits(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='testsuits', help_text='所属项目')	
    # include = models.TextField(null=False)	
    include = models.TextField('包含的接口', null=False, help_text='包含的接口')	
    class Meta:	
        db_table = 'tb_testsuits'	
        verbose_name = '套件信息'	
        verbose_name_plural = verbose_name	
    def __str__(self):	
        return self.name

projects需求

  • 删除项目时,只进行逻辑删除

  • 获取项目列表信息时,要求能获取此项目下的「接口总数」,「用例总数」,「配置总数」,「套件总数」,同时输出创建时间,格式为2019-11-05 11:43:00

  • 要求提供获取此项目下的所有项目名的接口

  • 要求提供获取此项目下的所有接口信息的接口

序列化器

from rest_framework import serializers	
from .models import Projects	
from debugtalks.models import DebugTalks	
from interfaces.models import Interfaces	
class ProjectModelSerializer(serializers.ModelSerializer):	
    class Meta:	
        model = Projects	
        exclude = ('update_time', 'is_delete')	
        extra_kwargs = {	
            'create_time': {	
                'read_only': True	
            }	
        }	
    def create(self, validated_data):	
        project_obj = super().create(validated_data)	
        DebugTalks.objects.create(project=project_obj)	
        return project_obj	
class ProjectNameSerializer(serializers.ModelSerializer):	
    class Meta:	
        model = Projects	
        fields = ('id', 'name')	
class InterfaceNameSerializer(serializers.ModelSerializer):	
    class Meta:	
        model = Interfaces	
        fields = ('id', 'name', 'tester')	
class InterfacesByProjectIdSerializer(serializers.ModelSerializer):	
    interfaces_set = InterfaceNameSerializer(read_only=True, many=True)	
    class Meta:	
        model = Projects	
        fields = ('id', 'interfaces_set')

视图

继承 ModelViewSet

from rest_framework.viewsets import ModelViewSet	
from rest_framework import permissions	
from rest_framework.decorators import action	
from rest_framework.response import Response	
from rest_framework.exceptions import NotFound	
from . import serializer	
from .models import Projects	
from .utils import get_count_by_project	
from interfaces.models import Interfaces	
class ProjectsViewSet(ModelViewSet):	
    """	
    list:	
    返回项目(多个)列表数据	
    create:	
    创建项目	
    retrieve:	
    返回项目(单个)详情数据	
    update:	
    更新(全)项目	
    partial_update:	
    更新(部分)项目	
    destroy:	
    删除项目	
    names:	
    返回所有项目ID和名称	
    interfaces:	
    返回某个项目的所有接口信息(ID和名称)	
    """	
    queryset = Projects.objects.filter(is_delete=False)	
    serializer_class = serializer.ProjectModelSerializer	
    permission_classes = (permissions.IsAuthenticated,)	
    ordering_fields = ('id', 'name')	
    def perform_destroy(self, instance):	
        instance.is_delete = True	
        instance.save()  # 逻辑删除	
    @action(methods=['get'], detail=False)	
    def names(self, request, *args, **kwargs):	
        queryset = self.get_queryset()	
        serializer = serializer.ProjectNameSerializer(instance=queryset, many=True)	
        return Response(serializer.data)	
    @action(methods=['get'], detail=True)	
    def interfaces(self, request, pk=None):	
        interface_objs = Interfaces.objects.filter(project_id=pk, is_delete=False)	
        one_list = []	
        for obj in interface_objs:	
            one_list.append({	
                'id': obj.id,	
                'name': obj.name	
            })	
        return Response(data=one_list)	
    def list(self, request, *args, **kwargs):	
        queryset = self.filter_queryset(self.get_queryset())	
        page = self.paginate_queryset(queryset)	
        if page is not None:	
            serializer = self.get_serializer(page, many=True)	
            datas = serializer.data	
            datas = get_count_by_project(datas)	
            return self.get_paginated_response(datas)	
        serializer = self.get_serializer(queryset, many=True)	
        datas = serializer.data	
        datas = get_count_by_project(datas)	
        return Response(datas)