1、任务概述
本次计划的核心任务是开发一个,个人版的公共用例库,旨在将各系统和各类测试场景下的通用、基础以及关键功能的测试用例进行系统性地归纳整理,并以提高用例的复用率为目标,力求最大限度地减少重复劳动,提升测试效率。
计划内容:完成公共用例库的开发实施工作,包括需求分析、系统设计、开发、测试、打包、运行维护等工作。
1.1、 已完成:
需求分析、数据库表的设计:公共用例库计划–个人版(一)
主体界面与逻辑设计:公共用例库计划–个人版(二)
导出Excel功能:公共用例库计划–个人版(三)
模块选择功能改造与性能优化公共用例库计划–个人版(四)
1.2、 本次待完成:
1. 首页的界面设计
2. 模块、用例与bug的数据显示
3. QtCharts制作饼图、柱状图
2、Qt Designer设计界面
文字显示用QLabel,数字显示用QLCDNumber,先设置显示5位数。下面放了两个QWidget,准备显示饼图与柱状图。调整布局、最小宽度高度就完事儿。
3、数据显示
模块、用例与bug的数据显示,只查询正常状态的模块与用例。
# ==============================================================================
# page 1.主页
# ==============================================================================
def number(self):
"""设置主页显示数据"""
self.case_db.connect()
case=self.case_db.query_one('select count(*) from testcase where status = 10') # 正常用例数
module=self.case_db.query_one('select count(*) from module where status = 10') # 正常模块数
bug=self.case_db.query_one("select count(*) from bug") # bug数
self.case_db.over()
self.case.mkNumber.display(module[0]) # 设置数字显示
self.case.caseNumber.display(case[0])
self.case.bugNumber.display(bug[0])
logging.info('主页显示数据')
现在界面显示出来是这样,(๑•̀ㅂ•́)و✧
4、QtCharts制作饼图、柱状图
pyqt6包里面没有QtCharts,需要pip安装:
pip install PyQt6-Charts
模块使用,各参考文章:
16000字++|Python GUI|PyQt/PySide|PySide6二维图表(1):QtCharts饼状/折线/柱形图、螺旋曲线等;matplotlib螺旋曲线、绘图路径绘图、绘制各种图形
PyQt中图表的建立与显示(完整过程演示)
PyQt5可视化 7 饼图和柱状图实操案例⑤
4.1、饼图
计划使用饼图显示:所有测试用例的类型分布,共有以下9种类型。
'tc_types': {'功能测试':20, '性能测试':21, '配置相关':22, '安装部署':23,'接口测试':24, '安全相关':25, '兼容性测试':26,
'UI测试':27, '其它':28}
4.1.1 用例类型数据
先查询出要显示的数据:
sql18="""select codes.value AS types,count(*) from testcase
INNER JOIN
codes ON testcase.types = codes.id AND codes.id BETWEEN 20 AND 28 -- 关联难度码值表
where testcase.status = 10
group by testcase.types"""
case_type=self.case_db.query_many(sql18) # 用例各类型数
运行得到以下数据:
[('功能测试', 55), ('性能测试', 1), ('配置相关', 1), ('安装部署', 2), ('接口测试', 1), ('安全相关', 1), ('UI测试', 5)]
4.1.2 饼图制作
将查询数据传入,先判断是否有饼图,有就清空数据,更新数据,没有就新建。
建立了do_pieHovered信号槽,鼠标放分块上时,分块弹出,label显示分块名称与百分比(解决显示不全的问题)
def case_type(self, value):
"""用例类型,饼图"""
if hasattr(self, 'charview') and self.charview: # 检查是否存在旧的饼图
chart=self.charview.chart()
chart.removeAllSeries() # 清空数据
else:
chart=QChart() # 创建图表
self.charview=QChartView(chart, self.case.pieChartView) # 定义charView窗口,添加chart元素
layout=self.case.pieChartView.layout() or QVBoxLayout(self.case.pieChartView)
layout.addWidget(self.charview)
pie_series=QPieSeries() # 创建QPieSeries对象,它用来存放饼图的数据
color_y2=((177, 217, 224), (149, 200, 217), (153, 207, 203), (118, 198, 200), (99, 175, 193), (120, 189, 161),
(154, 205, 169), (160, 221, 216), (183, 225, 215))
color_iterator=iter(color_y2) # 创建迭代器
for i in value:
slice=QPieSlice(i[0], i[1])
slice.setColor(QColor(*next(color_iterator))) # 设置颜色
pie_series.append(slice) # 设置饼图分块内容
#chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom) #图样,放下面
chart.legend().setVisible(False) # 不显示图样
chart.addSeries(pie_series)
font=QFont("Microsoft YaHei", 14) # 设置字体类型和大小
chart.setTitle("用例类型分布")
chart.setTitleFont(font)
pie_series.setLabelsVisible(True) # 只影响当前的slices,必须添加完slice之后再设置
pie_series.hovered.connect(self.do_pieHovered) # 鼠标落在某个分块上时,次分块弹出
self.charview.setRenderHint(QPainter.RenderHint.Antialiasing) # 设置抗锯齿
self.charview.show()
def do_pieHovered(self, pieSlice, state):
"""鼠标落在某个分块上时,次分块弹出"""
pieSlice.setExploded(state) # 弹回或缩回,具有动态效果
if state: # 显示带百分数的标签
self.__oldLabel=pieSlice.label() # 保存原来的label
pieSlice.setLabel(self.__oldLabel + ":%.1f%%"% (pieSlice.percentage() * 100))
self.case.label_10.setText(self.__oldLabel + ":%.1f%%"% (pieSlice.percentage() * 100))
else: # 显示原来的标签
pieSlice.setLabel(self.__oldLabel)
self.case.label_10.setText('')
4.1.3 实现情况
饼图自己生成的颜色全是蓝色,自己设置了好多个颜色都不咋满意,要不太艳要不太暗。ε=(´ο`*)))唉
鼠标放上分块,弹出。下面label显示分块名称与百分比:
4.2、柱状图
计划使用柱状图,显示顶级模块的用例数。
4.2.1 模块的用例数
先查询出要显示的数据。要返回顶级模块的名称,顶级模块及其子模块的所有用例数:
sql19="""SELECT
m1.moduleid || ':' || m1.modulename AS modulename_moduleid,
COUNT(t.caseid) AS total_cases
FROM
module AS m1
LEFT JOIN
module AS m2 ON m2.parent_path LIKE m1.moduleid || '/%' -- 使用LIKE操作符匹配子模块路径
JOIN
testcase t ON t.moduleid = m2.moduleid AND t.status = 10 -- 关联测试用例并筛选状态为10的用例
WHERE
m1.level = 0 -- 只选择顶级模块
GROUP BY
m1.moduleid; -- 按顶级模块ID分组计数"""
module_number=self.case_db.query_many(sql19) # 子模块用例数
sql21='''SELECT
m1.moduleid || ':' || m1.modulename AS modulename_moduleid,
COUNT(t.caseid) AS total_cases
FROM
(
SELECT
moduleid,
modulename
FROM
module
WHERE
level = 0
UNION ALL
SELECT
SUBSTR(parent_path, 0, INSTR(parent_path, '/') - 1) AS moduleid,
m2.modulename
FROM
module AS m2
WHERE
m2.parent_path LIKE '%/%' -- 包含至少一个子级的模块路径
) AS m1
JOIN
testcase t ON t.moduleid = m1.moduleid AND t.status = 10
GROUP BY
m1.moduleid;''' # 模块用例数
module_number2=self.case_db.query_many(sql21)
谁能帮帮菜鸟改下sql,一个sql我还查不出来。只有将两个sql的结果拼接了
module_counts={} # 柱状图,数据
for item in module_number: # 遍历第一个列表将数据加到字典中
module_name, count=item
module_counts[module_name]=count
for item in module_number2: # 遍历第二个列表并将数据累加到字典中
module_name, count=item
if module_name in module_counts:
module_counts[module_name]+=count
else:
module_counts[module_name]=count
得到数据:
{'66:冒烟测试': 5, '73:测试模块': 13, '12:web界面测试': 48}
4.2.2 柱状图制作
将查询数据传入,先判断是否有柱状图,有就清空数据,更新数据,没有就新建。
def module_number(self, value):
"""模块用例数,柱状图"""
if hasattr(self, 'chart_view') and self.chart_view: # 检查是否存在旧的图
chart=self.chart_view.chart()
chart.removeAllSeries() # 清空
for axis in chart.axes():
chart.removeAxis(axis) # 删除坐标轴
else:
# 创建图表
chart=QChart() # 确保这里已经定义了 chart 变量
self.chart_view=QChartView(chart)
bar_series=QBarSeries() # 创建数据集
bar_set=QBarSet('用例数')
color=((220, 103, 123), (81, 146, 171), (233, 130, 106), (99, 175, 193), (120, 189, 161), (255, 130, 130),
(149, 149, 149))
bar_set.setColor(QColor(*color[random.randint(0, 6)])) # 设置颜色
for v in value.values():
bar_set.append(v)
bar_series.append(bar_set) # 添加数据
bar_series.setLabelsVisible(True) # 数据点标签可见
bar_series.setLabelsFormat("@value") # 显示数值标签
bar_series.setLabelsPosition(QAbstractBarSeries.LabelsPosition.LabelsInsideEnd) # 数据标签显示位置
chart.addSeries(bar_series)
font=QFont("Microsoft YaHei", 14) # 设置字体类型和大小
chart.setTitle("顶级模块用例分布")
chart.setTitleFont(font)
chart.legend().setVisible(False) # 不显示图样
category_axis=QBarCategoryAxis() # 创建mk轴并设置模块名称与ID
#category_axis.setLabelsAngle(45) # 设置模块名称斜着显示
self.keys=list(value.keys()) # x轴名称列表
category_axis.setCategories(self.keys) # 将所有keys一次性设置为轴标签
chart.addAxis(category_axis, Qt.AlignmentFlag.AlignBottom) #添加到图表chart中,并将其设置为底部对齐
bar_series.attachAxis(category_axis)
bar_series.hovered.connect(self.do_barSeries_Hovered) # hovered信号,获取条形的具体数据
value_axis=QValueAxis() # 创建数值轴并设置范围
max_value=math.ceil(max(value.values()) *1.05)
value_axis.setMax(max_value) # 根据实际数据调整最大值
value_axis.setLabelFormat("%d") # 精度
chart.addAxis(value_axis, Qt.AlignmentFlag.AlignLeft)
bar_series.attachAxis(value_axis)
self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing) # 创建图表视图并将图表添加进去
layout=self.case.widget_13.layout() or QVBoxLayout(self.case.widget_13) # 布局
layout.addWidget(self.chart_view)
def do_barSeries_Hovered(self, status, index, barset):
"""获取鼠标下柱体数据,显示到标签"""
if status:
hint="%s————%s=%d" % (self.keys[index],barset.label(), barset.at(index))
else:
hint=""
self.case.label_9.setText(hint) # 标签显示详情
4.2.3 实现情况
鼠标放上柱体。下面label显示模块名称与用例数: