上一章我们完成了列表组件公共化封装和项目管理功能的实现,这一章将实现用例概览页功能,用于测试项目的测试情况的一个统计展示。
为了开发效率,很多类型都是用any
来定义的,小伙伴可以自己进行完善
完整教程地址:《从0搭建自动化测试平台》
项目在线演示地址:http://121.43.43.59/ (帐号:admin 密码:123456)
本章内容实现效果如下:
之前有小伙伴反应多次点击会出现消息重复弹出的情况,如下图所示:
我们可以修改antd的message组件的配置来设置它的显示最大数量、位置、持续时间等,例如下面的代码:
import { message } from 'antd';
message.config({
top: 100, //位置
duration: 2,//持续时间
maxCount: 1,//显示的最大数量
});
在app.tsx
中加入上述代码即可。
1)首先在代码项目下执行创建用例模块的命令:
django-admin startapp cases
后面用例相关(用例模块、报告等)都会放到这里面进行管理。
2)建立用例模块表,表模型如下:
from django.db import models
from comFunc.comModel import ComModel
from project.models import Project
class Module(ComModel):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name="模块名称")
status0 = models.IntegerField(default=0, verbose_name="等待执行")
status1 = models.IntegerField(default=0, verbose_name="执行失败")
status2 = models.IntegerField(default=0, verbose_name="正在执行")
status3 = models.IntegerField(default=0, verbose_name="执行完成(接口用例特有状态)")
status4 = models.IntegerField(default=0, verbose_name="执行通过")
status = models.IntegerField(verbose_name="模块状态")
parent = models.ForeignKey(to='self', verbose_name="父模块", null=True, on_delete=models.DO_NOTHING)
project = models.ForeignKey(to=Project, on_delete=models.DO_NOTHING, default=1, verbose_name="关联的项目id")
type = models.IntegerField(verbose_name="模块类型")
class Meta:
verbose_name = '用例模块'
db_table = 'module'
类似的增删改查代码根据之间的教学进行CURD开发即可。
1)概览列表接口的功能是将项目下模块不同状态数量进行查询并汇总,没有模块的项目默认全部为0,我们可以先查项目表,然后使用django里orm的反向查询它的模块数据,没有模块的全部设为0即可,代码如下:
def case_overview(request):
""" 用例概览情况 """
case_type = request.query_params['type'] # 代表查询UI还是API用例概览情况
projects = Project.objects.filter(type=case_type)
value_fields = {f'status{i}': Sum(f'status{i}') for i in range(5)}
value_fields.update(
{'project_name': F('project__name'), 'project_status': F('project__status'),
'total': F('status0') + F('status1') + F('status2') + F('status3') + F('status4')})
res_data = []
for project in projects:
data = project.module_set.filter(parent_id=None).values('project_id').annotate(**value_fields).first()
res_data.append(data or {**{f'status{i}': 0 for i in range(5)},
**{'project_id': project.id, 'project_status': project.status,
'project_name': project.name, 'total': 0}})
return Response(data=res_data)
这样的实现性能上会查一些,因为每个项目都会进行一次模块的反查,这样每多一个项目就会多一次sql的查询。
更好的做法是直接将两张表的数据都查出来,然后代码中做组合,小伙伴们可以自己动手去实现。
2)按照上面实现的概览接口使用时会报错,这是因为返回的是queryset
类似list
的这种类型的数据,我们之前开发的中间件没有适配这种情况,需要修改中间件来进行兼容,修改后的中间件核心代码如下:
if res_data is not None:
if isinstance(res_data, dict):
if 'code' not in res_data:
if 'data' in res_data:
response.data.update({'code': status.HTTP_200_OK, 'msg': ''})
else: # delete请求返回的数据没有data,所以下面的逻辑需要单独处理
response.data = {'code': status.HTTP_200_OK,
'msg': res_data.pop('msg', ''),
'data': res_data}
elif isinstance(res_data, (list, QuerySet)):
response.data = {'code': status.HTTP_200_OK, 'data': res_data, 'msg': ''}
注:需要在头部引入QuerySet
:
from django.db.models import QuerySet
首先,还是执行创建cases页面模块的文件:
npx umi g page cases/index --typescript
根据演示效果我们可以看到,用例管理是一个有子级的菜单。
这里我们只需要在.umirc.ts
配置文件加入嵌套routes即可,代码如下:
{
name: '用例管理',
icon: 'case',
path: '/case',
routes: [
{
name: '自动化UI用例管理',
path: '/case/uiCaseOverview',
component: '@/pages/caseOverview',
},
{
name: '自动化Api用例管理',
path: '/case/apiCaseOverview',
component: '@/pages/caseOverview',
},
],
},
这样修改完成后我们就能够在页面上看到如下的菜单效果了:
概览页使用了antd
的栅格布局来排版,然后结合Card
组件实现了如下的效果:
最后结合请求的路由地址不同给请求概览页接口带上不同的type
参数,将其返回的数据按上述组件格式进行遍历添加,就能够实现最终的效果了:
完整index.tsx
代码如下:
import React, { useState, useEffect } from 'react';
import { PROJECT_STATUS_TAG } from '@/globalEnum';
import { caseOverview } from '@/services/cases';
import { Card, Col, Spin, Tag, Button, Badge, message, Row } from 'antd';
const CaseOverview: React.FC = (props: any) => {
const type = props.match.path === '/case/uiCaseOverview' ? 1 : 2;
const [loading, setLoading] = useState<boolean>(true);
const [cardItems, setcardItems] = useState<any>([]);
useEffect(() => {
caseOverview({ type: type }).then((res) => {
const cards = res.data.map((item: any) => (
<Col key={item.project_id} span={8}>
<Card
title={
<div>
<h3 style={{ fontWeight: 'bold', display: 'inline' }}>
{item.project_name}
</h3>
<Button
style={{ float: 'right' }}
onClick={() => message.warning('待实现')}
>
管理UI元素
</Button>
</div>
}
>
<Tag
style={{ float: 'right', height: '2em' }}
color={PROJECT_STATUS_TAG[item.project_status].color}
>
{PROJECT_STATUS_TAG[item.project_status].text}
</Tag>
<ul style={{ listStyleType: 'none', padding: 0 }}>
<Badge status="error" text="用例失败数量:" />
{item.status1}
<li>
<Badge status="default" text="等待执行数量:" />
{item.status0}
</li>
<li>
<Badge status="warning" text="正在执行数量:" />
{item.status2}
</li>
<li>
<Badge status="processing" text="执行完成数量:" />
{item.status3}
</li>
<li>
<Badge status="success" text="测试通过数量:" />
{item.status4}
</li>
</ul>
<h3 style={{ float: 'right' }}>用例总数量:{item.total}</h3>
</Card>
</Col>
));
setcardItems(cards);
setLoading(false);
});
}, []);
return (
<Spin spinning={loading}>
<div
style={{
overflowX: 'hidden',
overflowY: 'auto',
height: 'calc(100vh - 100px)',
}}
>
<Row gutter={[16, 16]}>{cardItems}</Row>
</div>
</Spin>
);
};
export default React.memo(CaseOverview);
globalEnum.ts
新增代码如下:
export const PROJECT_STATUS_TAG = {
0: { text: '项目进行中', color: '#faad14' },
1: { text: '项目已完成', color: '#52c41a' },
}; //代表请求列表
cases
服务层接口请求代码如下:
import { request } from 'umi';
export function caseOverview(params: any) {
return request<any>('/cases/overview', { params });
}
这一章没有复杂的内容,基本都是重复的CURD。下一章节会正式开始自动化用例模块相关的教学和开发了。
平台在线演示地址:http://121.43.43.59/ (帐号:admin 密码:123456)
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/momoda118/article/details/122083690
内容来源于网络,如有侵权,请联系作者删除!