直播伴侣高分屏适配测试用例(Qt 客户端)
直播伴侣高分屏适配测试用例(Qt 客户端)
| 用例编号 | 用例名称 | 目的 | 前置条件 | 环境 / 测试数据 | 步骤 | 预期结果 | 实际结果 | 通过/失败 | 备注 |
|---|---|---|---|---|---|---|---|---|---|
| HDP-001 | 单监视器 200% 缩放自适应 | 验证在单个 200% DPI(如 1920×1080 200%)下程序是否能正确自适应并保持 UI 清晰 | - 电脑仅连接一台高 DPI 显示器(200%) - 关闭系统自带缩放(仅程序自适应) |
- Windows10 1909 - Qt 5.15 / 6.2 - 直播伴侣 vX.X |
1. 打开系统设置 → 显示 → 缩放比例设为 200% 2. 重启电脑或手动重启应用 3. 启动直播伴侣 |
① 程序窗口尺寸为原始尺寸的 2 倍 ② UI 元素(按钮、文字、图像)无拉伸、无模糊 ③ 文字大小保持可读(如 12pt 变为 24pt) |
|||
| HDP-002 | 双显示器跨屏拖拽无漂移 | 验证在主副屏 DPI 不同(如 100% & 200%)的环境下,窗口拖拽到另一屏时位置是否正确 | - 电脑连接两台显示器: ① 主屏:1920×1080 100% ② 副屏:2560×1440 200% - 两屏横向并排、无物理隔离 |
同 HDP-001 | 1. 启动直播伴侣,默认打开窗口在主屏 2. 记录窗口左上角坐标(主屏) 3. 用鼠标拖拽窗口至副屏 4. 记录副屏坐标 5. 将窗口拖回主屏 |
① 位置漂移(如坐标不连续)不出现 ② 窗口尺寸按 DPI 自动缩放(主屏 1×,副屏 2×) ③ 拖拽过程无闪烁、无跨屏跳失 |
|||
| HDP-003 | 动态 DPI 调整自适应 | 验证程序能在运行时实时响应系统 DPI 改变 | - 同 HDP-001 - 运行时可以通过系统设置实时切换缩放比例 |
同 HDP-001 | 1. 启动直播伴侣 2. 打开系统设置,实时切换缩放比例:100% → 125% → 150% → 200% → 125% 3. 观察窗口尺寸、UI 元素比例是否随之变化 4. 记录每一次 DPI 改变时窗口状态 |
① 窗口尺寸按新的 DPI 自动缩放 ② UI 元素不出现模糊或拉伸 ③ 运行时不出现闪退、UI 卡顿 |
|||
| HDP-004 | 小屏显示不被放大导致操作受限 | 验证在低分辨率屏幕(如 1366×768 150%)上,UI 仍能完整显示且不被过度放大 | - 电脑连接三台显示器: ① 主屏 1920×1080 200% ② 副屏 1366×768 150% ③ 另一个 2560×1440 100% |
同 HDP-001 | 1. 在副屏(1366×768 150%)启动直播伴侣 2. 观察窗口是否被放大到不可操作的大小 3. 记录窗口尺寸、UI 元素布局 |
① 窗口尺寸不超过屏幕尺寸 ② UI 元素均可点击、可视(无遮挡) ③ 界面不出现滚动条或裁剪 |
|||
| HDP-005 | 文本与图像清晰度验证 | 验证在所有 DPI 设定下,文本与图像无失真、无模糊 | - 同 HDP-001 - 选取代表性文本(如 14pt)和高分辨率图标 |
同 HDP-001 | 1. 在不同 DPI 下截图窗口(100%、125%、150%、200%) 2. 逐一比较截图与预置清晰度基准(同尺寸、同 DPI 的无缩放截图) 3. 使用图像编辑软件对比像素级差异(可用工具:ImageMagick diff) |
① 文本像素边缘无锯齿、无模糊 ② 图像尺寸保持整数倍,图标清晰无失真 |
测试环境与工具
| 项目 | 说明 |
|---|---|
| 操作系统 | Windows 10/11(桌面)、macOS Monterey(Qt 6) |
| Qt 版本 | 5.15.2、6.2.0 |
| 直播伴侣版本 | 1.3.5(已集成 DPI 自适应) |
| 硬件 | 3 台显示器,分别配置 100%、150%、200% 缩放 |
| 辅助工具 | Snipping Tool / Greenshot(截图) ImageMagick(像素对比) Visual Studio(日志查看) |
通过/失败判定
- 通过:所有预期结果均满足,未出现位置漂移、UI 异常、模糊或尺寸超屏现象。
- 失败:出现任何预期结果不符(例如:位置漂移、UI 拉伸、文本模糊、窗口尺寸超屏),均需记录截图并提交缺陷。
缺陷上报
- 缺陷编号:HDP‑<YYYYMMDD‑NNN>
- 标题:简要描述问题(如 “双屏拖拽导致位置漂移”)
- 复现步骤:引用对应测试用例编号
- 环境:记录操作系统、Qt 版本、显示器 DPI 组合
- 预期结果 / 实际结果:完整对照
- 截图 / 日志:附上截图或相关日志文件
提示:在多显示器环境下,请先确保所有显示器已正确连接并设置了对应的 DPI,重启后再执行测试,以免缓存导致错误。
关键点回顾
- 自适应 DPI:程序在任何 DPI 组合下都能自适应窗口大小与 UI 元素比例。
- 跨屏拖拽:窗口在不同 DPI 显示器间拖拽时不出现漂移或跳失。
- 运行时动态 DPI:支持系统 DPI 变化时实时调整。
- 清晰显示:文本与图像在任何缩放比例下保持清晰,无模糊。
- 小屏兼容:低分辨率屏幕仍可完整展示 UI,且不被过度放大导致操作受限。
完成上述测试后,若全部用例通过,即可确认直播伴侣已实现高分屏下“水土不服”的优化。祝测试顺利!
test_high_dpi.py – 自动化测试脚本(Windows / Qt 5/6)
该脚本使用 PyTest + pytest‑qt 进行 Qt UI 交互,配合 pywinauto 控制窗口位置、Pillow 对截图做像素差异对比。
仅供参考,实际运行时请根据自己的测试环境(多屏、DPI、App 路径)做相应配置。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
=========================================================
测试脚本:high_dpi_tests.py
=========================================================
功能
-----
1. ① 单屏 200% DPI 下窗口尺寸与 UI 适配
2. ② 双屏跨 DPI 拖拽不出现位置漂移
3. ③ 运行时 DPI 动态切换
4. ④ 小屏(低分辨率)兼容
5. ⑤ 文本与图片在任何缩放比例下保持清晰
依赖
-----
pip install pytest pytest-qt pywinauto pillow numpy
使用
-----
1. 先手动完成系统 DPI 设置(例如:在 Windows 里把 1 屏 200% 100%,再手动配置双屏)。
**注意**:更改系统 DPI 后需要重启桌面或重启电脑,自动化脚本中不做这一步。
2. 把 `APP_PATH` 设为待测直播伴侣可执行文件的绝对路径。
3. 运行:`pytest test_high_dpi.py` 或 `python test_high_dpi.py`
脚本结构
---------
- `setup_app` : 启动 App 并返回 pywinauto 的 WindowSpecification 对象
- `capture_window` : 取窗口全景截图
- `compare_images` : 计算两张图片的像素差异(阈值)
- `drag_window_across_screens` : 模拟窗口跨屏拖拽
- 5 个 `test_*` 函数对应 5 条测试用例
> **提示**
> * 在多屏环境下,建议给每个显示器设置一个唯一的 DPI 组合,并在运行测试前确认系统已按需求配置。
> * 由于系统 DPI 改变会影响窗口全局 DPI,脚本中只演示核心逻辑;实际环境需手工调整或使用脚本编辑注册表后重启。
=========================================================
"""
import os
import time
import subprocess
import pytest
import numpy as np
from PIL import Image, ImageChops
# --------------------------- 配置 --------------------------- #
# 1. 路径(请自行修改为你们的可执行文件路径)
APP_PATH = r"C:\Program Files\LivePartner\LivePartner.exe"
# 2. 用于 DPI 变更的占位函数(实际环境需自行实现)
def set_system_dpi(scale_factor: float):
"""
在测试环境中手动或脚本设置系统 DPI。该占位实现仅为演示,实际需修改 Windows 注册表或使用
PowerShell/DisplaySettings 调整。请确保在调用前已重启桌面或电脑。
"""
# TODO: 在 Windows 上可以通过
# reg add "HKCU\Control Panel\Desktop" /v LogPixels /t REG_DWORD /d <值> /f
# 然后执行 `shutdown /r /t 0` 或重启 explorer.exe
# 这里仅打印日志,实际测试请手工完成
print(f"[INFO] 请手动将系统 DPI 设置为 {scale_factor * 100:.0f}% 并重启桌面。")
time.sleep(2) # 等待手工完成
# 3. 启动应用并返回 pywinauto WindowSpecification
def start_app() -> subprocess.Popen:
"""使用 subprocess 启动应用程序(非 Qt 应用的 QProcess)"""
process = subprocess.Popen([APP_PATH], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(5) # 等待 UI 完全加载
return process
def get_main_window(process) -> 'pywinauto.application.WindowSpecification':
"""
根据进程 ID 获取主窗口(使用 pywinauto 的 `WindowSpecification`)
"""
from pywinauto.application import Application
app = Application(backend="uia").connect(process=process.pid)
# 假设主窗口标题包含“LivePartner”
win = app.window(title_re=".*LivePartner.*")
win.wait("visible", timeout=30)
return win
# 4. 截图工具
def capture_window_screenshot(win) -> Image.Image:
"""使用 pywinauto 的截图(基于 pillow)"""
rect = win.rectangle()
# Pillow 通过坐标截取屏幕区域
img = Image.grab(bbox=(rect.left, rect.top, rect.right, rect.bottom))
return img
# 5. 比较两张图片的像素差异
def compare_images(img1: Image.Image, img2: Image.Image, threshold: float = 0.01) -> bool:
"""
计算两张图片的平均像素差异,阈值为 0~1(默认 1%):
- 0 代表完全相同
- 小于 threshold 视为相似
"""
diff = ImageChops.difference(img1, img2)
# 转为灰度图
diff = diff.convert("L")
arr = np.array(diff)
# 计算平均差异值
mean_diff = arr.mean() / 255.0
return mean_diff < threshold
# 6. 拖拽窗口跨屏
def drag_window_across_screens(win, target_rect):
"""
将窗口移动到目标位置(通常是另一显示器的坐标范围内)
"""
# pywinauto 通过 set_window_text 或 set_window_pos
win.move_window(x=target_rect["x"], y=target_rect["y"], width=target_rect["width"], height=target_rect["height"])
# --------------------------- 测试用例 --------------------------- #
@pytest.fixture(scope="module")
def app_process():
"""启动应用程序并返回进程对象"""
proc = start_app()
yield proc
# 结束进程
proc.terminate()
proc.wait(timeout=10)
@pytest.fixture
def main_win(app_process):
"""返回主窗口对象(pywinauto WindowSpecification)"""
win = get_main_window(app_process)
return win
def test_single_monitor_200_percent(main_win):
"""① 单屏 200% DPI 下窗口尺寸与 UI 适配"""
set_system_dpi(2.0) # 手工完成
# 取窗口尺寸
rect = main_win.rectangle()
# 期望尺寸:根据设计宽度 800px * 2 = 1600px,取一个代表性控件大小检查
# 这里仅检查窗口宽度是否 >= 1500px
assert rect.width >= 1500, f"窗口宽度不足,实际 {rect.width}px"
# 截图与标准截图比较(标准截图已在项目中准备好)
img = capture_window_screenshot(main_win)
std_img_path = os.path.join("resources", "single_200_std.png")
std_img = Image.open(std_img_path)
assert compare_images(img, std_img, threshold=0.02), "单屏 200% DPI 截图不一致"
def test_dual_monitor_cross_screen_drag(main_win):
"""② 双屏跨屏拖拽无漂移"""
# 假设监视器 A (左) 100% DPI, 监视器 B (右) 200% DPI
# 取 A 的左上角坐标作为起点
rect_A = main_win.rectangle()
# 移到 B(右侧)—— 右侧屏的左上角 1000px 处
target = {"x": rect_A.left + 2000, "y": rect_A.top, "width": rect_A.width, "height": rect_A.height}
drag_window_across_screens(main_win, target)
time.sleep(1) # 等窗口稳定
rect_B = main_win.rectangle()
# 判断窗口是否真的在 B 的坐标区
assert rect_B.left >= rect_A.left + 1900, "窗口未正确位于 B 屏"
# 截图检查
img = capture_window_screenshot(main_win)
std_img_path = os.path.join("resources", "dual_drag_std.png")
std_img = Image.open(std_img_path)
assert compare_images(img, std_img, threshold=0.02), "跨屏拖拽后截图不一致"
def test_dynamic_dpi_change(main_win):
"""③ 运行时 DPI 动态切换"""
# ① 先 100% DPI,截图
set_system_dpi(1.0)
std_img_100 = Image.open(os.path.join("resources", "dynamic_100_std.png"))
img_100 = capture_window_screenshot(main_win)
assert compare_images(img_100, std_img_100, threshold=0.02), "100% DPI 截图不一致"
# ② 切换到 200% DPI
set_system_dpi(2.0)
# 重新拉取窗口尺寸(假设窗口会自动缩放)
time.sleep(2)
std_img_200 = Image.open(os.path.join("resources", "dynamic_200_std.png"))
img_200 = capture_window_screenshot(main_win)
assert compare_images(img_200, std_img_200, threshold=0.02), "200% DPI 截图不一致"
def test_small_screen_compatibility(main_win):
"""③ 小屏低分辨率兼容性"""
set_system_dpi(0.5) # 手工完成:50% DPI
rect = main_win.rectangle()
# 期望窗口高度不小于 800px(假设设计 400px * 2)
assert rect.height >= 800, f"窗口高度不足,实际 {rect.height}px"
img = capture_window_screenshot(main_win)
std_img = Image.open(os.path.join("resources", "small_std.png"))
assert compare_images(img, std_img, threshold=0.02), "小屏 DPI 截图不一致"
def test_text_and_image_clearance(main_win):
"""⑤ 文本与图片在任何缩放比例下保持清晰"""
# ① 先 100% DPI
set_system_dpi(1.0)
# 取代表性文本框高度(设计 30px)
rect = main_win.rectangle()
# 期望高度 >= 25px(有 5% 容忍)
assert rect.height >= 25, f"100% DPI 文本框高度不足,实际 {rect.height}px"
img_100 = capture_window_screenshot(main_win)
std_100 = Image.open(os.path.join("resources", "text_img_100_std.png"))
assert compare_images(img_100, std_100, threshold=0.02), "100% DPI 文本/图片不清晰"
# ② 200% DPI
set_system_dpi(2.0)
img_200 = capture_window_screenshot(main_win)
std_200 = Image.open(os.path.join("resources", "text_img_200_std.png"))
assert compare_images(img_200, std_200, threshold=0.02), "200% DPI 文本/图片不清晰"
# --------------------------- 入口 --------------------------- #
if __name__ == "__main__":
pytest.main([__file__])
说明 & 进一步改进
| 需求 | 关键实现 | 进一步改进建议 |
|---|---|---|
| 单屏 200% DPI 适配 | 取窗口宽度、对比标准截图 | 通过 main_win.get_size() 与已知设计尺寸做算术验证;可结合 win32api.GetDeviceCaps 取得 DPI |
| 双屏跨屏拖拽 | move_window() 直接定位 |
结合 AutoIt 或 DisplaySwitch.exe 进一步验证显示器 DPI 计算 |
| 运行时 DPI 动态切换 | 重新拉起 App 并传入 --scale=2.0(假设 App 支持) |
在 App 启动参数里支持 --dpi=xx,测试时直接传入不同值 |
| 小屏兼容 | 检查窗口高度、宽度是否不低于期望 | 可通过 win32api.GetDeviceCaps 获取物理 DPI,做动态计算 |
| 文本/图片清晰度 | 取 PNG 的 ImageChops.difference 计算平均差异 |
对 threshold 采用自适应阈值(如 0.02)或使用 structural similarity index (SSIM) 进一步细化 |
如果你们的测试平台不是 Windows,或者使用 macOS / Linux,可以改用 PyAutoGUI + OpenCV 取屏幕截图,使用 SikuliX 或 Robot 控制跨屏拖拽。核心思路完全一致,只是 API 不同即可。
祝测试顺利 🚀!

浙公网安备 33010602011771号