仿QQ音乐--GUI测试报告
摘要:本文介绍了一个基于Vue+HTML+CSS+JavaScript开发的仿QQ音乐在线音乐平台项目。项目实现了歌曲播放、歌词同步、搜索、歌单管理等核心功能,采用前后端分离架构。通过详细的测试用例验证了播放控制(播放/暂停、随机/顺序/单曲循环)、音量调节、歌曲导入、喜欢列表管理等功能的正确性。测试包括功能验证和用户体验评估,并实现了自动化测试脚本,涵盖推荐页面、歌词页面等模块的测试。项目通过组
一、项目背景
本项目为仿QQ音乐在线音乐平台,采用Vue + HTML + CSS + JavaScript 开发,基于前后端分离架构实现。完成歌曲播放、歌词同步、搜索、歌单管理、播放控制、首页推荐等核心功能,界面与交互高度还原官方产品。通过接口请求、组件化开发、音频控制等技术,实现完整业务流程,提升了前端工程化与项目实战能力。
二、项目功能
1.播放与暂停功能:当你点击进入仿QQ音乐项目时,你会发现中心底部它会有个三角形,你进行点击会播放你所选中的音乐,再点击一次,音乐就会暂停
2.随机播放:当你点击随机播放时,你当前的这首歌播放完后,会随机跳到下一首歌曲,但是不一定是按顺序播放,它可能跳到第三首或者第四首。单曲循环:当你点击单曲循环时,你点击一首歌曲,歌曲播放完后,它下次播放的还是当前这首歌曲。顺序播放:当你点击顺序循环时,你点击一首歌曲,歌曲播放完后,它下次播放的是按顺序的第二首歌曲
3.音量调节大小:点击音量,调节声音大小
4.导入歌曲:点击"+"号将我们需要的音乐导入进去,才能进行播放
5.播放全部:点击播放全部,它会从第一首歌曲开始播放
6.最小化:点击"-"号,会将画面隐藏起来
7.添加/删除 喜欢:点击歌曲前面的爱心按钮,歌曲会被添加进我喜欢里面,再次点击爱心按钮,我喜欢里面会去除这首歌曲
8.上一曲/下一曲:点击|<|按钮歌曲会回到上一首歌曲,点击|>|按钮歌曲会跳转到下一首歌曲
7.搜索:搜索框能输入文字
三、测试目的
1.功能验证
- 确保核心功能实现,如暂停与播放能正常使用
- 需要的歌曲能正常导入进去,实现播放
- 播放模式:随机播放/单曲循环/顺序播放能正常使用
2.用户体验
- 评估界面布局的合理性和易用性
- 检查页面上的按钮是否能正常使用
四、测试用例

五、自动化测试
创建一个tests,分别创建test_command.py、test_like.py、test_local.py、test_recommend.py、test_songwords.py五个模块测试不同页面的功能

公共模块:测试logo、测试搜索功能、测试换皮肤功能、测试最小化、测试导入音乐、测试随机播放、测试单曲循环、测试顺序循环
公共模块
测试logo:界面正常打开,测试通过
# 测试logo
def test_log(self,QQMusic_app):
logo_ele=read_yaml("logo")
logo=QQMusic_app.win.child_window(auto_id=logo_ele['auto_id'], control_type=logo_ele['control_type'])
logo.wait("visible")


测试搜索功能:界面打开,搜索框输入"周杰伦",测试通过
# 测试搜索功能
def test_search(self,QQMusic_app):
edit_ele=read_yaml("search")
edit=QQMusic_app.win.child_window(auto_id=edit_ele['auto_id'], control_type=edit_ele['control_type'])
# 唤起输入框
edit.click_input()
# ctrl+a全部选中之后再输入关键词,就不会存在追加情况
edit.type_keys("^a周杰伦")

测试换皮肤功能:点击换皮肤,出现文本,测试通过
# 测试换皮肤功能
def test_skin(self,QQMusic_app):
skin_ele=read_yaml("换肤")
skin=QQMusic_app.win.child_window(auto_id=skin_ele['auto_id'], control_type=skin_ele['control_type'])
# 点击换皮肤入口,唤起弹窗
skin.click_input()
# 验证弹窗以及文本信息
warning=QQMusic_app.win.child_window(title="温馨提示",control_type="Window")
warning.wait("visible")
warn_text=warning.child_window(control_type="Text").window_text()
assert warn_text=="换肤功能小哥哥正在紧急支持中..."
# 关闭温馨提示弹窗
warning.close()
# 测试弹窗是否正确关闭
warning.wait_not("visible")

测试最小化:进入页面最下化,页面隐藏,测试通过
# 测试最小化
def test_window_min(self,QQMusic_app):
window_min_ele=read_yaml("最小化")
window_min_btn=QQMusic_app.win.child_window(auto_id= window_min_ele['auto_id'],
control_type= window_min_ele['control_type'])
# 点击最小化按钮
window_min_btn.click_input()
# 测试一下QQ音乐窗口是否已经最小化了
assert QQMusic_app.win.is_minimized()
# 还原
QQMusic_app.win.restore()

测试导入音乐:进入页面,点击"+"按钮导入歌曲,测试通过
#测试导入音乐
def test_importMusic(self,QQMusic_app):
import_ele=read_yaml("导入音乐")
import_btn=QQMusic_app.win.child_window(auto_id= import_ele['auto_id'],
control_type= import_ele['control_type'])
# 点击导入音乐按钮
import_btn.click_input()
#定位添加本地下载音乐窗口
import_win=QQMusic_app.win.child_window(title="添加本地下载音乐",control_type="Window")
import_win.wait("visible")
# 选中所有音乐添加
music_list=import_win.child_window(title="项目视图",control_type="List")
# 打开音乐:1)通过按钮实现2)enter实现
music_list.type_keys("^a{ENTER}")
import_win.wait_not("visible")

测试随机播放:随机播放三首歌曲,三首歌曲不一样,测试通过
#测试随机播放
def test_play_random(self, QQMusic_app):
# 点击播放全部
local_ele = read_yaml("本地下载")
play_all_ele = local_ele["播放全部"]
play_btn = QQMusic_app.win.child_window(auto_id=play_all_ele['auto_id'],
control_type=play_all_ele['control_type'])
for i in range(1, 4):
# 点击播放全部,从第一首歌曲开始播放(2002年的第一场雪)
play_btn.click_input()
# 将歌曲播放进度拉到尾部
play_ele = read_yaml("播放控制")
process_line_ele = play_ele["播放总进度"]
process_line = QQMusic_app.win.child_window(auto_id=process_line_ele['auto_id'],
control_type=process_line_ele['control_type'])
# 获取进度条的尺寸
rec = process_line.rectangle()
x = rec.right - 3
y = math.floor((rec.top + rec.bottom) / 2)
# 鼠标点击进度条的尾部
mouse.click(coords=(x, y))
# 等待切换下一曲
time.sleep(2)
# 检查下一步是否为列表中第二首歌曲
# 1)若是,随机播放模式不一定错误
# 2)若不是,随机播放模式正确
music_name_ele = play_ele["歌曲名"]
music_name = QQMusic_app.win.child_window(auto_id=music_name_ele['auto_id'],
control_type=music_name_ele['control_type']).window_text()
if music_name != "Andy阿杜":
self.logger.info(f"第{i}次判断随机播放下一曲正确")
return
else:
self.logger.info(f"第{i}次判断随机播放下一曲错误")
# 走到这里还没有返回
raise Exception("随机播放下一曲三次判断均错误")

测试单曲循环:播放一首歌曲,歌曲播放完后,播放原来歌曲,测试通过

#测试单曲循环
def test_play_single(self, QQMusic_app):
# 点击播放全部
local_ele = read_yaml("本地下载")
play_all_ele = local_ele["播放全部"]
play_btn = QQMusic_app.win.child_window(auto_id=play_all_ele['auto_id'],
control_type=play_all_ele['control_type'])
# 切换模式:随机播放——单曲循环
play_ele = read_yaml("播放控制")
playMode_ele = play_ele["模式切换"]
playMode_btn = QQMusic_app.win.child_window(auto_id=playMode_ele['auto_id'],
control_type=playMode_ele['control_type'])
# 点击切换模式按钮
playMode_btn.click_input()
for i in range(1, 4):
# 点击播放全部按钮
play_btn.click_input()
music_name_ele = play_ele["歌曲名"]
music_name_before = QQMusic_app.win.child_window(auto_id=music_name_ele['auto_id'],
control_type=music_name_ele['control_type']).window_text()
# 将歌曲播放进度拉到尾部
process_line_ele = play_ele["播放总进度"]
process_line = QQMusic_app.win.child_window(auto_id=process_line_ele['auto_id'],
control_type=process_line_ele['control_type'])
# 获取进度条的尺寸
rec = process_line.rectangle()
x = rec.right - 3
y = math.floor((rec.top + rec.bottom) / 2)
# 鼠标点击进度条的尾部
mouse.click(coords=(x, y))
# 等待切换下一曲
time.sleep(2)
# 下一首播放的歌曲和前一首歌曲是否相同
# 1)相同,单曲循环模式不一定正确---多次验证
# 2)不相同,单曲循环模式错误
music_name_after = QQMusic_app.win.child_window(auto_id=music_name_ele['auto_id'],
control_type=music_name_ele['control_type']).window_text()
if music_name_before != music_name_after:
self.logger.error(
f"单曲循环模式播放下一首歌曲校验错误,before:{music_name_before},after:{music_name_after}")
break
else:
self.logger.info(f"第{i}次校验单曲循环模式播放下一首歌曲正确")
if i == 3:
return
raise Exception(f"单曲循环模式播放下一首歌曲校验错误,before:{music_name_before},after:{music_name_after}")
测试列表循环:下拉至最后一首歌曲,拖动进度,播放第一曲,测试通过

#测试列表循环
def test_play_circle(self, QQMusic_app):
# 切换模式:单曲循环——列表循环
play_ele = read_yaml("播放控制")
music_name_ele = play_ele["歌曲名"]
playMode_ele = play_ele["模式切换"]
playMode_btn = QQMusic_app.win.child_window(auto_id=playMode_ele['auto_id'],
control_type=playMode_ele['control_type'])
# 点击切换模式按钮
playMode_btn.click_input()
for i in range(1, 4):
# 找到列表中最后一首歌曲
music_list_ele = read_yaml("歌曲列表")
music_list = QQMusic_app.win.child_window(auto_id=music_list_ele['auto_id'],
control_type=music_list_ele['control_type'])
# 获取歌曲列表的中间坐标
list_mid = music_list.rectangle().mid_point()
# 鼠标下拉列表使其展示最后一首歌曲
mouse.scroll(coords=(list_mid.x, list_mid.y), wheel_dist=-500)
# 获取最后一首歌曲——求列表中列表项目数
list_size = music_list.item_count()
# 双击最后一首歌曲,使其播放
last_music_mid = music_list.get_item(row=list_size - 1).rectangle().mid_point()
mouse.double_click(coords=(last_music_mid.x, last_music_mid.y))
# 拉取进度条到尾部,等待播放下一曲
process_line_ele = play_ele["播放总进度"]
process_line = QQMusic_app.win.child_window(auto_id=process_line_ele['auto_id'],
control_type=process_line_ele['control_type'])
# 获取进度条的尺寸
rec = process_line.rectangle()
x = rec.right - 3
y = math.floor((rec.top + rec.bottom) / 2)
# 鼠标点击进度条的尾部
mouse.click(coords=(x, y))
# 等待切换下一曲
time.sleep(2)
# 校验播放的下一首歌曲是否为“2002年的第一场雪(列表的第一首歌曲)”
# 1)是,列表循环校验不一定正确
# 2)不是,列表循环校验错误
music_name = QQMusic_app.win.child_window(auto_id=music_name_ele['auto_id'],
control_type=music_name_ele['control_type']).window_text()
if music_name != "2002年的第一场雪":
self.logger.error(f"列表循环下一曲错误,music_name:{music_name}")
break
else:
self.logger.info(f"第{i}次校验列表循环下一曲正确")
if i == 3:
return
raise Exception(f"列表循环下一曲错误,music_name:{music_name}")
我喜欢
我喜欢模块:测试我喜欢文本、测试我喜欢播放全部、测试我喜欢模块-标记喜欢、测试我喜欢模块—选择歌曲双击播放、
测试我喜欢文本
![]()
def test_like_text(self,QQMusic_app):
like_ele = read_yaml("我喜欢")
#点击导航栏“我喜欢”进入到我喜欢模块
like_btn = QQMusic_app.win.child_window(auto_id=like_ele["auto_id"],
control_type=like_ele["control_type"])
like_btn.click_input()
#测试“我喜欢”文本
like_text_ele = like_ele["我喜欢文本"]
like_text = QQMusic_app.win.child_window(auto_id=like_text_ele["auto_id"],
control_type=like_text_ele["control_type"]).window_text()
assert like_text == "我喜欢"
#测试“歌曲名称”文本
songname_text_ele = like_ele["歌曲名称文本"]
songname_text = QQMusic_app.win.child_window(auto_id=songname_text_ele["auto_id"],
control_type=songname_text_ele["control_type"]).window_text()
assert songname_text == "歌曲名称"
#测试“歌手名称”文本
singername_text_ele = like_ele["歌手名称文本"]
singername_text = QQMusic_app.win.child_window(auto_id=singername_text_ele["auto_id"],
control_type=singername_text_ele["control_type"]).window_text()
assert singername_text == "歌手名称"
#测试“专辑名称”文本
albumrname_text_ele = like_ele["专辑名称文本"]
albumrname_text = QQMusic_app.win.child_window(auto_id=albumrname_text_ele["auto_id"],
control_type=albumrname_text_ele["control_type"]).window_text()
assert albumrname_text == "专辑名称"
测试我喜欢播放全部
![]()
'''
我喜欢模块——播放全部
'''
def test_like_playAll(self,QQMusic_app):
playAll_ele = read_yaml("我喜欢")["播放全部"]
playAll_btn = QQMusic_app.win.child_window(auto_id=playAll_ele["auto_id"],
control_type=playAll_ele["control_type"])
#点击播放全部按钮
playAll_btn.click_input()
#获取播放进度
process_line_ele = read_yaml("播放控制")["当前播放进度"]
process_line_before = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_before = process_line_before.rectangle().right
#等待两秒
time.sleep(2)
#获取播放进度
process_line_after = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_after = process_line_after.rectangle().right
#比较前后两次进度变化,有变化则说明按钮没有问题
assert process_line_len_before != process_line_len_after
测试我喜欢模块-标记喜欢
![]()
'''
我喜欢模块——测试标记喜欢
'''
def test_mark_unLike(self,QQMusic_app):
#获取歌曲列表中歌曲的数量
music_list_ele = read_yaml("我喜欢")["歌曲列表"]
music_list_before = QQMusic_app.win.child_window(auto_id=music_list_ele["auto_id"],
control_type=music_list_ele["control_type"])
# 获取歌曲列表歌曲数量
list_size_before = music_list_before.item_count()
#取消标记喜欢
rec = music_list_before.get_item(row=0).rectangle()
y = math.floor((rec.top + rec.bottom)/2)
x = rec.left + 22
mouse.click(coords=(x,y))
#获取歌曲列表中歌曲的数量
music_list_after = QQMusic_app.win.child_window(auto_id=music_list_ele["auto_id"],
control_type=music_list_ele["control_type"])
# 获取歌曲列表歌曲数量
list_size_after = music_list_after.item_count()
#测试取消标记喜欢是否成功
assert list_size_after + 1 == list_size_before
测试我喜欢模块—选择歌曲双击播放
![]()
'''
我喜欢模块——选择歌曲双击播放
'''
def test_like_playSingle(self,QQMusic_app):
music_list_ele = read_yaml("我喜欢")["歌曲列表"]
music_list = QQMusic_app.win.child_window(auto_id=music_list_ele["auto_id"],
control_type=music_list_ele["control_type"])
#获取歌曲列表歌曲数量
list_size = music_list.item_count()
if list_size <= 0:
assert 0,"歌曲列表为空"
#选择第一首歌曲双击播放
point = music_list.get_item(row=0).rectangle().mid_point()
mouse.double_click(coords=(point.x,point.y))
# 获取播放进度
process_line_ele = read_yaml("播放控制")["当前播放进度"]
process_line_before = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_before = process_line_before.rectangle().right
# 等待两秒
time.sleep(2)
# 获取播放进度
process_line_after = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_after = process_line_after.rectangle().right
# 比较前后两次进度变化,有变化则说明双击歌曲播放没有问题
assert process_line_len_before != process_line_len_after
本地下载
本地下载模块:测试本地下载模块—文本、测试本地下载播放全部功能、测试本地下载模块选择歌曲并双击播放、测试将歌曲标记喜欢
测试本地下载模块—文本
![]()
# '''
# 测试本地下载模块——文本
# “本地音乐、歌曲名称、歌手名称、专辑名称”
# '''
def test_local_text(self,QQMusic_app):
local_ele = read_yaml("本地下载")
#点击导航栏-本地下载,进入本地下载页面
local = QQMusic_app.win.child_window(auto_id=local_ele["auto_id"],
control_type=local_ele["control_type"])
local.click_input()
#测试“本地音乐文本"
local_text_ele = local_ele["本地音乐文本"]
local_text = QQMusic_app.win.child_window(auto_id=local_text_ele["auto_id"],
control_type=local_text_ele["control_type"]).window_text()
assert local_text == "本地音乐"
#测试“歌曲名称文本"
songname_text_ele = local_ele["歌曲名称文本"]
songname_text = QQMusic_app.win.child_window(auto_id=songname_text_ele["auto_id"],
control_type=songname_text_ele["control_type"]).window_text()
print(songname_text)
assert songname_text == "歌曲名称"
#测试“歌手名称文本"
singername_text_ele = local_ele["歌手名称文本"]
singername_text = QQMusic_app.win.child_window(auto_id=singername_text_ele["auto_id"],
control_type=singername_text_ele["control_type"]).window_text()
assert singername_text == "歌手名称"
测试本地下载播放全部功能
![]()
'''
测试本地下载模块——播放全部功能
'''
def test_local_playAll(self,QQMusic_app):
local_ele = read_yaml("本地下载")
playAll_ele = local_ele["播放全部"]
playAll_btn = QQMusic_app.win.child_window(auto_id=playAll_ele["auto_id"],
control_type=playAll_ele["control_type"])
#点击播放全部按钮
playAll_btn.click_input()
#获取播放进度
process_line_ele = read_yaml("播放控制")["当前播放进度"]
process_line_before = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_before = process_line_before.rectangle().right
#等待两秒
time.sleep(2)
#获取播放进度
process_line_after = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_after = process_line_after.rectangle().right
#测试前后两个进度是否存在差别
assert process_line_len_before != process_line_len_after
测试本地下载模块——选择歌曲并双击播放
![]()
'''
测试本地下载模块——选择歌曲并双击播放
'''
def test_local_playSingle(self,QQMusic_app):
music_list_ele = read_yaml("歌曲列表")
music_list = QQMusic_app.win.child_window(auto_id=music_list_ele["auto_id"],
control_type=music_list_ele["control_type"])
#将歌曲列表还原到最上方——————公共模块测试循环播放找最后一首歌曲将列表拉到了最下面
point = music_list.rectangle().mid_point()
mouse.scroll(coords=(point.x,point.y),wheel_dist=500)
#获取歌曲列表中歌曲数量
if music_list.item_count() <= 0:
assert 0,"歌曲列表为空"
#选择一首歌曲并双击播放
point = music_list.get_item(row=0).rectangle().mid_point()
mouse.double_click(coords=(point.x,point.y))
# 获取播放进度
process_line_ele = read_yaml("播放控制")["当前播放进度"]
process_line_before = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_before = process_line_before.rectangle().right
# 等待两秒
time.sleep(2)
# 获取播放进度
process_line_after = QQMusic_app.win.child_window(auto_id=process_line_ele["auto_id"],
control_type=process_line_ele["control_type"])
process_line_len_after = process_line_after.rectangle().right
# 测试前后两个进度是否存在差别
assert process_line_len_before != process_line_len_after
测试将歌曲标记喜欢
![]()
'''
将歌曲标记喜欢——为了后面我喜欢模块的测试提供数据
'''
def test_mark_like(self,QQMusic_app):
#获取歌曲列表中歌曲数量
music_list_ele = read_yaml("歌曲列表")
music_list = QQMusic_app.win.child_window(auto_id=music_list_ele["auto_id"],
control_type=music_list_ele["control_type"])
list_size = music_list.item_count()
#对每一首歌曲标记喜欢
for i in range(0,list_size):
if i != 0 and i % 6 == 0:
#6及以后的歌曲在标记喜欢之前需要先向下滑动,使其显示出来
point = music_list.rectangle().mid_point()
mouse.scroll(coords=(point.x,point.y),wheel_dist=-500)
rec = music_list.get_item(row=i).rectangle()
#获取爱心的中间位置(x,y)
y = math.floor((rec.top + rec.bottom)/2)
x = rec.left + 22
mouse.click(coords=(x,y))
推荐页面
推荐模块:测试—推荐页面的文本、测试今日为你推荐滚动区域——左滚动、测试今日为你推荐滚动区域—右滚动、测试你的音乐补给滚动区域—左滚动、测试你的音乐补给滚动区域—右滚动
测试—推荐页面的文本
推荐、今日为你推荐、你的音乐补给
![]()
'''
测试——推荐页面的文本
"推荐、今日为你推荐、你的音乐补给"
'''
def test_rec_text(self,QQMusic_app):
#点击左侧的推荐导航入口,进入到推荐页面
rec_ele = read_yaml("推荐")
rec_btn = QQMusic_app.win.child_window(auto_id=rec_ele["auto_id"],
control_type=rec_ele["control_type"])
rec_btn.click_input()
#获取“推荐”文本控件
rec_text_ele = rec_ele["推荐文本"]
#获取“今日为你推荐”文本控件
rec_foru_text_ele = rec_ele["今日为你推荐文本"]
#获取“你的音乐补给”文本控件
rec_supply_text_ele = rec_ele["你的音乐补给文本"]
#校验“推荐”文本控件
rec_text = QQMusic_app.win.child_window(auto_id=rec_text_ele["auto_id"],
control_type=rec_text_ele["control_type"])
assert rec_text.window_text() == "推荐"
# 校验“今日为你推荐”文本控件
rec_foru_text = QQMusic_app.win.child_window(auto_id=rec_foru_text_ele["auto_id"],
control_type=rec_foru_text_ele["control_type"])
assert rec_foru_text.window_text() == "今日为你推荐"
#校验“你的音乐补给”文本控件
rec_supply_text = QQMusic_app.win.child_window(auto_id=rec_supply_text_ele["auto_id"],
control_type=rec_supply_text_ele["control_type"])
assert rec_supply_text.window_text() == "你的音乐补给"
测试今日为你推荐滚动区域——左滚动
![]()
'''
测试今日为你推荐滚动区域——左滚动
'''
def test_recforu_scroll_left(self,QQMusic_app):
rec_ele = read_yaml("推荐")
item_text_ele = rec_ele["今日为你推荐第一项文本"]
item_text_before = QQMusic_app.win.child_window(auto_id=item_text_ele["auto_id"],
control_type=item_text_ele["control_type"],
found_index=0).window_text()
scroll_left_ele = rec_ele["今日为你推荐左滚动"]
scroll_left = QQMusic_app.win.child_window(auto_id=scroll_left_ele["auto_id"],
control_type=scroll_left_ele["control_type"])
#点击左滚动按钮
scroll_left.click_input()
#获取推荐项的名称,进行前后对比校验
item_text_after = QQMusic_app.win.child_window(auto_id=item_text_ele["auto_id"],
control_type=item_text_ele["control_type"],
found_index=0).window_text()
assert item_text_before != item_text_after
测试今日为你推荐滚动区域—右滚动
![]()
'''
测试今日为你推荐滚动区域——右滚动
'''
def test_recforu_scroll_right(self, QQMusic_app):
rec_ele = read_yaml("推荐")
item_text_ele = rec_ele["今日为你推荐第一项文本"]
item_text_before = QQMusic_app.win.child_window(auto_id=item_text_ele["auto_id"],
control_type=item_text_ele["control_type"],
found_index=0).window_text()
scroll_right_ele = rec_ele["今日为你推荐右滚动"]
scroll_right = QQMusic_app.win.child_window(auto_id=scroll_right_ele["auto_id"],
control_type=scroll_right_ele["control_type"])
# 点击右滚动按钮
scroll_right.click_input()
# 获取推荐项的名称,进行前后对比校验
item_text_after = QQMusic_app.win.child_window(auto_id=item_text_ele["auto_id"],
control_type=item_text_ele["control_type"],
found_index=0).window_text()
assert item_text_before != item_text_after
测试你的音乐补给滚动区域—左滚动
![]()
'''
测试——你的音乐补给滚动区域——左滚动
'''
def test_supply_scroll_left(self,QQMusic_app):
rec_ele = read_yaml("推荐")
all_rec_area_ele = rec_ele["推荐整个模块"]
all_rec_area = QQMusic_app.win.child_window(auto_id=all_rec_area_ele["auto_id"],
control_type=all_rec_area_ele["control_type"])
#找推荐整个模块的中间坐标
point = all_rec_area.rectangle().mid_point()
#在推荐模块鼠标下拉,展示完整的为你推荐区域
mouse.scroll(coords=(point.x,point.y),wheel_dist=-500)
#点击左滚动按钮
scroll_left_ele = rec_ele["音乐补给左滚动"]
one_one_ele = rec_ele["音乐补给第一排第一项文本"]
two_one_ele = rec_ele["音乐补给第二排第一项文本"]
one_one_text_before = QQMusic_app.win.child_window(auto_id=one_one_ele["auto_id"],
control_type=one_one_ele["control_type"],
found_index=0).window_text()
two_one_text_before = QQMusic_app.win.child_window(auto_id=two_one_ele["auto_id"],
control_type=two_one_ele["control_type"],
found_index=0).window_text()
scroll_left_btn = QQMusic_app.win.child_window(auto_id=scroll_left_ele["auto_id"],
control_type=scroll_left_ele["control_type"])
scroll_left_btn.click_input()
#左滚动结果的校验--项目名称是否变化
one_one_text_after = QQMusic_app.win.child_window(auto_id=one_one_ele["auto_id"],
control_type=one_one_ele["control_type"],
found_index=0).window_text()
two_one_text_after = QQMusic_app.win.child_window(auto_id=two_one_ele["auto_id"],
control_type=two_one_ele["control_type"],
found_index=0).window_text()
assert one_one_text_after != one_one_text_before
assert two_one_text_after != two_one_text_before
测试你的音乐补给滚动区域—右滚动
![]()
'''
测试——你的音乐补给滚动区域——右滚动
'''
def test_supply_scroll_right(self, QQMusic_app):
rec_ele = read_yaml("推荐")
all_rec_area_ele = rec_ele["推荐整个模块"]
all_rec_area = QQMusic_app.win.child_window(auto_id=all_rec_area_ele["auto_id"],
control_type=all_rec_area_ele["control_type"])
# 找推荐整个模块的中间坐标
point = all_rec_area.rectangle().mid_point()
# 在推荐模块鼠标下拉,展示完整的为你推荐区域
mouse.scroll(coords=(point.x, point.y), wheel_dist=-500)
# 点击右滚动按钮
scroll_left_ele = rec_ele["音乐补给右滚动"]
one_one_ele = rec_ele["音乐补给第一排第一项文本"]
two_one_ele = rec_ele["音乐补给第二排第一项文本"]
one_one_text_before = QQMusic_app.win.child_window(auto_id=one_one_ele["auto_id"],
control_type=one_one_ele["control_type"],
found_index=0).window_text()
two_one_text_before = QQMusic_app.win.child_window(auto_id=two_one_ele["auto_id"],
control_type=two_one_ele["control_type"],
found_index=0).window_text()
scroll_right_btn = QQMusic_app.win.child_window(auto_id=scroll_left_ele["auto_id"],
control_type=scroll_left_ele["control_type"])
scroll_right_btn.click_input()
# 左滚动结果的校验--项目名称是否变化
one_one_text_after = QQMusic_app.win.child_window(auto_id=one_one_ele["auto_id"],
control_type=one_one_ele["control_type"],
found_index=0).window_text()
two_one_text_after = QQMusic_app.win.child_window(auto_id=two_one_ele["auto_id"],
control_type=two_one_ele["control_type"],
found_index=0).window_text()
assert one_one_text_after != one_one_text_before
assert two_one_text_after != two_one_text_before
歌词页面
歌词模块:测试歌词页面的标题、歌手名、歌曲名、测试歌词页面--测试歌词
测试歌词页面的标题、歌手名、歌曲名
![]()
'''
测试歌词页面的标题
“歌手名、歌曲名”
'''
def test_titie_text(self,QQMusic_app):
song_word_page_ele = read_yaml("歌词入口")
song_word_btn = QQMusic_app.win.child_window(auto_id=song_word_page_ele["auto_id"],
control_type=song_word_page_ele["control_type"])
#点击页面的歌词入口,进入到歌词页面
song_word_btn.click_input()
#获取歌手名文本
singer_text_ele = song_word_page_ele["歌手标题文本"]
singer_text = QQMusic_app.win.child_window(auto_id=singer_text_ele["auto_id"],
control_type=singer_text_ele["control_type"]).window_text()
#校验歌手名文本
assert singer_text == "刀郎"
#获取歌曲名文本
song_text_ele = song_word_page_ele["歌曲名标题文本"]
song_text = QQMusic_app.win.child_window(auto_id=song_text_ele["auto_id"],
control_type=song_text_ele["control_type"]).window_text()
#校验歌曲名文本
assert song_text == "2002年的第一场雪"
测试歌词页面--测试歌词
从头播放歌曲并立即暂停————才能获取到歌词列表中的歌手名和歌曲名
![]()
'''
歌词页面——测试歌词
从头播放歌曲并立即暂停————才能获取到歌词列表中的歌手名和歌曲名
'''
def test_songwords(self,QQMusic_app):
likepage_ele = read_yaml("我喜欢")
wordspage_ele = read_yaml("歌词入口")
#收起歌词页面
hide_word_page_ele = wordspage_ele["收起歌词"]
hide_word_page_btn = QQMusic_app.win.child_window(auto_id=hide_word_page_ele["auto_id"],
control_type=hide_word_page_ele["control_type"])
hide_word_page_btn.click_input()
# 为后面的测试用例做准备————点击播放歌曲并立即暂停
playAll_ele = likepage_ele["播放全部"]
playAll_btn = QQMusic_app.win.child_window(auto_id=playAll_ele["auto_id"],
control_type=playAll_ele["control_type"])
playAll_btn.click_input()
# 立即暂停播放
play_ele = read_yaml("播放控制")["播放"]
play_btn = QQMusic_app.win.child_window(auto_id=play_ele["auto_id"],
control_type=play_ele["control_type"])
play_btn.click_input()
# 获取当前正在播放的歌手名和歌曲名
play_control_ele = read_yaml("播放控制")
singer_name_ele = play_control_ele["歌手名"]
song_name_ele = play_control_ele["歌曲名"]
singer_name = QQMusic_app.win.child_window(auto_id=singer_name_ele["auto_id"],
control_type=singer_name_ele["control_type"]).window_text()
song_name = QQMusic_app.win.child_window(auto_id=song_name_ele["auto_id"],
control_type=song_name_ele["control_type"]).window_text()
# songwordsText = f"{song_name} - {singer_name}"
#进入歌词页面
song_word_page_ele = read_yaml("歌词入口")
song_word_btn = QQMusic_app.win.child_window(auto_id=song_word_page_ele["auto_id"],
control_type=song_word_page_ele["control_type"])
# 点击页面的歌词入口,进入到歌词页面
song_word_btn.click_input()
#测试歌词
words_list_ele = wordspage_ele["歌词列表"]
words_list = QQMusic_app.win.child_window(auto_id=words_list_ele["auto_id"],
control_type=words_list_ele["control_type"])
for i in words_list.children():
if i.window_text() in song_name or i.window_text() in singer_name:
return
self.logger.info(f"获取到的歌词:{i.window_text()}")
#始终没有匹配上
raise Exception(f"歌词匹配失败,song_name:{song_name},singer_name{singer_name}")
测试工具类:方便打印信息,和定位窗口

logUtils.py:日志打印

import logging
import time
import os.path
class InfoFilter(logging.Filter):
def filter(self, record):
return record.levelno == logging.INFO
class ErrFilter(logging.Filter):
def filter(self, record):
return record.levelno == logging.ERROR
class Logger:
logger=None
@classmethod
def getlog(cls):
# 创建日志对象
if cls.logger is None:
cls.logger=logging.getLogger(__name__)
# 设置日志级别
cls.logger.setLevel(logging.DEBUG)
LOG_PATH="log/"
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
# 2026-03-02.log
now=time.strftime("%Y-%m-%d")
logname=LOG_PATH+now+".log"
info_logname=LOG_PATH+now+"_info.log"
err_logname=LOG_PATH+now+"_err.log"
# 创建总日志文件处理器
handler=logging.FileHandler(logname,encoding="utf-8")
# 创建info日志文件处理器
info_handler=logging.FileHandler(info_logname,encoding="utf-8")
# 添加文件过滤
info_handler.addFilter(InfoFilter())
# 创建err日志文件处理器
err_handler=logging.FileHandler(err_logname,encoding="utf-8")
# 添加文件过滤
err_handler.addFilter(ErrFilter())
# 设置日志格式
formatter=logging.Formatter(
"%(asctime)s %(levelname)s [%(name)s] [%(filename)s (%(funcName)s:%(lineno)d] - %(message)s"
)
handler.setFormatter(formatter)
info_handler.setFormatter(formatter)
err_handler.setFormatter(formatter)
# 给logger对象添加handler
cls.logger.addHandler(handler)
cls.logger.addHandler(info_handler)
cls.logger.addHandler(err_handler)
return cls.logger
yamlUtils.py
import os
import yaml
def read_yaml(key):
with open(os.getcwd()+"/data/elements.yml",mode="r",encoding="utf-8") as f:
data=yaml.safe_load(f)
return data[key]
仿QQ音乐启动与关闭
import pytest
from pywinauto import Application
from utils.logUtils import Logger
class QQmusicApp:
def __init__(self):
self.app_path = r"D:\qqmusic\qqmusic\QQMusic.exe"
self.logger = Logger.getlog()
self.app = None
self.win = None
#启动QQmusic程序
def launch(self):
try:
# self.app = Application(backend="uia").start(self.app_path)
#测试代码
self.app = Application(backend="uia").connect(process=174720)
#定位窗口
self.win = self.app.window(title="QQMusic")
self.win.wait("visible")
self.logger.info("应用程序启动成功!")
# self.win.print_control_identifiers()
except Exception as e:
self.logger.error(f"应用程序启动失败:{e}")
#关闭QQmusic程序
def close(self):
if self.win:
self.win.close()
@pytest.fixture(scope="session")
def QQMusic_app():
QQmusic = QQmusicApp()
QQmusic.launch()
yield QQmusic
QQmusic.close()
自动化测试全部通过图片实列

测试配置

六、测试报告
allure generate .\reports\source\ -o .\reports\html 生成测试报告

点击进入浏览器,生成测试报告

可以点击进去,查看相关测试用例

更多推荐
所有评论(0)