fix: 1、集成letmego方案;2、新增了报告默认展示信息;3、修复了一些已知问题;

Description:

Log:
This commit is contained in:
mikigo 2023-08-29 18:12:45 +08:00
parent a2030218f6
commit 6e5368f770
14 changed files with 172 additions and 90 deletions

View File

@ -48,6 +48,9 @@ log_setting.CLASS_NAME_STARTSWITH = GlobalConfig.CLASS_NAME_STARTSWITH
log_setting.CLASS_NAME_ENDSWITH = GlobalConfig.CLASS_NAME_ENDSWITH
log_setting.CLASS_NAME_CONTAIN = GlobalConfig.CLASS_NAME_CONTAIN
from letmego import write_testcase_running_status
from letmego import read_testcase_running_status
from setting import skipif
from setting.globalconfig import ConfStr
from setting.globalconfig import FixedCsvTitle
@ -158,13 +161,16 @@ def pytest_addoption(parser):
"--duringfail", action="store_true", dest="duringfail", default=False, help="出现错误时立即显示"
)
parser.addoption(
'--repeat', action='store', default=1, type=int, help='用例重复执行的次数'
'--repeat', action='store', default=1, type=int, help="用例重复执行的次数"
)
parser.addoption(
'--exportcsv', action='store', default="", help='导出测试用例文件'
'--exportcsv', action='store', default="", help="导出测试用例文件"
)
parser.addoption(
'--line', action='store', default="", help='业务线(CI)'
'--line', action='store', default="", help="业务线(CI)"
)
parser.addoption(
'--autostart', action='store', default="", help="用例执行程序注册到开机自启服务"
)
@ -457,6 +463,13 @@ def pytest_collection_modifyitems(session):
# 批量执行时不执行没有ID的用例。
logger.error(f"<{item.name}> csv文件中未标记,强制跳过")
session.items.remove(item)
if session.config.option.autostart:
for item in session.items[::-1]:
_letmego = read_testcase_running_status(item)
if _letmego:
session.items.remove(item)
if (suite_id or task_id) and session.items:
print("\n即将执行的用例:")
for item in session.items:
@ -614,6 +627,9 @@ def pytest_runtest_makereport(item, call):
if write_json(item.session):
# 只要是需要数据回填(无论是自动还是手动),都需要写json结果.
write_case_result(item, report)
if item.config.option.autostart:
write_testcase_running_status(item)
try:
if item.execution_count >= (int(item.config.option.record_failed_case) + 1):
if report.when == "call": # 存放录屏当次测试结果

1
env.sh
View File

@ -133,6 +133,7 @@ pip_array=(
pdocr-rpc
image-center
allure-custom
letmego
)
if [ "${ENV_CUT_FLAG}" = "cut" ]; then

View File

@ -72,6 +72,7 @@ pip_array=(
allure-custom
funnylog
image-center
letmego
)
# 裁剪基础环境
if [ "${ENV_CUT_FLAG}" = "cut" ]; then

View File

@ -77,6 +77,7 @@ class Manage:
build_env=None,
client_password=None,
parallel=None,
autostart=None,
):
self.default_app = app
self.default_keywords = keywords
@ -114,6 +115,7 @@ class Manage:
self.default_build_env = build_env
self.default_client_password = client_password
self.default_parallel = parallel
self.default_autostart = autostart
say(GlobalConfig.PROJECT_NAME)
version_font = "slick"
@ -306,6 +308,9 @@ class Manage:
sub_parser_run.add_argument(
"--line", default="", help="执行的业务线写入json文件"
)
sub_parser_run.add_argument(
"--autostart", default="", help="用例执行程序注册到开机自启服务"
)
args = parser.parse_args()
local_kwargs = {
Args.app_name.value: args.app or self.default_app,
@ -339,6 +344,7 @@ class Manage:
Args.project_name.value: args.project_name or self.default_project_name,
Args.build_location.value: args.build_location or self.default_build_location,
Args.line.value: args.line or self.default_line,
Args.autostart.value: args.autostart or self.default_autostart,
}
return local_kwargs, args

View File

@ -2,7 +2,7 @@
addopts =
-s
-vv
--durations=10
--durations=3
--no-header
--verbosity=2
--show-capture=no

View File

@ -78,6 +78,9 @@ REPEAT =
;yes, 测试过程中立即显示报错
DURING_FAIL = no
;注册自启服务
AUTOSTART =
;=============================== REPORT CONFIG ===================================
[report]
;测试报告的title

View File

@ -85,6 +85,7 @@ class _GlobalConfig:
NOSKIP = runner_cfg.get_bool("NOSKIP", default=False)
IFIXED = runner_cfg.get_bool("IFIXED", default=False)
DURING_FAIL = runner_cfg.get_bool("DURING_FAIL", default=False)
AUTOSTART = runner_cfg.get_bool("AUTOSTART", default=False)
TOP = runner_cfg.get("TOP", default="")
REPEAT = runner_cfg.get("REPEAT", default="")
DEB_PATH = runner_cfg.get("DEB_PATH", default="~/Downloads/")

View File

@ -18,7 +18,6 @@ if sys.version_info[0] == 2 or sys.version_info[0:2] in ((3, 1), (3, 7)):
# the mouse.
MINIMUM_DURATION = 0.1
# If sleep_amount is less than MINIMUM_DURATION, sleep() will be a no-op and the mouse cursor moves there instantly.
# TODO: This value should vary with the platform. http://stackoverflow.com/q/1133857
MINIMUM_SLEEP = 0.05
STEP_SLEEP = 10
@ -377,7 +376,7 @@ def size():
return Size(posx, posy)
def moveTo(x=None, y=None, duration=0.0, tween=linear, logScreenshot=False, _pause=True):
def moveTo(x=None, y=None, duration=0.0, tween=linear, _pause=True):
startx, starty = position()
x = int(x) if x is not None else startx
@ -399,13 +398,10 @@ def moveTo(x=None, y=None, duration=0.0, tween=linear, logScreenshot=False, _pau
if sleep_amount < MINIMUM_SLEEP:
num_steps = int(duration / MINIMUM_SLEEP)
sleep_amount = duration / num_steps
# print(str(startx) + "," + str(starty))
# print(str(x) + "," + str(y))
steps = [getPointOnLine(startx, starty, x, y, tween(n / num_steps)) for n in range(num_steps)]
# Making sure the last position is the actual destination.
# print(steps)
steps.append((x, y))
# print(steps)
for tweenX, tweenY in steps:
if len(steps) > 1:
# A single step does not require tweening.
@ -417,30 +413,49 @@ def moveTo(x=None, y=None, duration=0.0, tween=linear, logScreenshot=False, _pau
f"{dbus_cmd}.moveTo int32:{str(tweenX)} int32:{str(tweenY)}"
)
def moveRel(
xOffset=0, yOffset=0, duration=0.0, tween=linear, _pause=True,
):
if xOffset is None:
xOffset = 0
if yOffset is None:
yOffset = 0
def mouseDown(x=None, y=None, button=PRIMARY, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
if type(xOffset) in (tuple, list):
xOffset, yOffset = xOffset[0], xOffset[1]
if xOffset == 0 and yOffset == 0:
return # no-op case
mousex, mousey = position()
mousex = mousex + xOffset
mousey = mousey + yOffset
moveTo(mousex, mousey, duration, tween)
move = moveRel
def mouseDown(x=None, y=None, button=PRIMARY, duration=0.0, tween=linear, _pause=True):
x, y = _normalizeXYArgs(x, y)
moveTo(x, y, duration, tween, logScreenshot, _pause)
moveTo(x, y, duration, tween, _pause)
system(
f"{dbus_cmd}.mouseDown string:{button}"
)
sleep(0.3)
def mouseUp(x=None, y=None, button=PRIMARY, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
def mouseUp(x=None, y=None, button=PRIMARY, duration=0.0, tween=linear, _pause=True):
x, y = _normalizeXYArgs(x, y)
moveTo(x, y, duration, tween, logScreenshot, _pause)
moveTo(x, y, duration, tween, _pause)
system(
f"{dbus_cmd}.mouseUp string:{button}"
)
def click(
x=None, y=None, clicks=1, interval=0.0, button=PRIMARY, duration=0.0, tween=linear, logScreenshot=None,
_pause=True
x=None, y=None, clicks=1, interval=0.0, button=PRIMARY, duration=0.0, tween=linear, _pause=True
):
x, y = _normalizeXYArgs(x, y)
moveTo(x, y, duration, tween, logScreenshot, _pause)
moveTo(x, y, duration, tween, _pause)
for i in range(clicks):
if button in (LEFT, MIDDLE, RIGHT):
system(
@ -449,35 +464,35 @@ def click(
sleep(interval)
def leftClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
click(x, y, 1, interval, LEFT, duration, tween, logScreenshot, _pause=_pause)
def leftClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, _pause=True):
click(x, y, 1, interval, LEFT, duration, tween, _pause=_pause)
def rightClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
click(x, y, 1, interval, RIGHT, duration, tween, logScreenshot, _pause=_pause)
def rightClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, _pause=True):
click(x, y, 1, interval, RIGHT, duration, tween, _pause=_pause)
def middleClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
click(x, y, 1, interval, MIDDLE, duration, tween, logScreenshot, _pause=_pause)
def middleClick(x=None, y=None, interval=0.0, duration=0.0, tween=linear, _pause=True):
click(x, y, 1, interval, MIDDLE, duration, tween, _pause=_pause)
def doubleClick(x=None, y=None, interval=0.0, button=LEFT, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
click(x, y, 2, interval, button, duration, tween, logScreenshot, _pause=False)
def doubleClick(x=None, y=None, interval=0.0, button=LEFT, duration=0.0, tween=linear, _pause=True):
click(x, y, 2, interval, button, duration, tween, _pause=False)
def tripleClick(x=None, y=None, interval=0.0, button=LEFT, duration=0.0, tween=linear, logScreenshot=None, _pause=True):
click(x, y, 3, interval, button, duration, tween, logScreenshot, _pause=False)
def tripleClick(x=None, y=None, interval=0.0, button=LEFT, duration=0.0, tween=linear, _pause=True):
click(x, y, 3, interval, button, duration, tween, _pause=False)
def scroll(clicks, x=None, y=None, logScreenshot=None, _pause=True):
def scroll(clicks, x=None, y=None, _pause=True):
if type(x) in (tuple, list):
x, y = x[0], x[1]
x, y = position(x, y)
moveTo(x, y)
vscroll(clicks, x, y, logScreenshot, _pause)
vscroll(clicks, x, y, _pause)
def hscroll(clicks, x=None, y=None, logScreenshot=None, _pause=True):
def hscroll(clicks, x=None, y=None, _pause=True):
if type(x) in (tuple, list):
x, y = x[0], x[1]
x, y = position(x, y)
@ -490,7 +505,7 @@ def hscroll(clicks, x=None, y=None, logScreenshot=None, _pause=True):
sleep(0.05)
def vscroll(clicks, x=None, y=None, logScreenshot=None, _pause=True):
def vscroll(clicks, x=None, y=None, _pause=True):
if type(x) in (tuple, list):
x, y = x[0], x[1]
x, y = position(x, y)
@ -504,18 +519,18 @@ def vscroll(clicks, x=None, y=None, logScreenshot=None, _pause=True):
def dragTo(
x=None, y=None, duration=0.0, tween=linear, button=PRIMARY, logScreenshot=None, _pause=True, mouseDownUp=True
x=None, y=None, duration=0.0, tween=linear, button=PRIMARY, _pause=True, mouseDownUp=True
):
x, y = _normalizeXYArgs(x, y)
if mouseDownUp:
mouseDown(button=button, logScreenshot=False, _pause=False)
mouseDown(button=button, _pause=False)
moveTo(x, y, duration, tween)
if mouseDownUp:
mouseUp(button=button, logScreenshot=False, _pause=False)
mouseUp(button=button, _pause=False)
def dragRel(
xOffset=0, yOffset=0, duration=0.0, tween=linear, button=PRIMARY, logScreenshot=None, _pause=True,
xOffset=0, yOffset=0, duration=0.0, tween=linear, button=PRIMARY, _pause=True,
mouseDownUp=True
):
if xOffset is None:
@ -531,15 +546,15 @@ def dragRel(
mousex, mousey = position()
mousex = mousex + xOffset
mousey = mousey + mousey
mousey = mousey + yOffset
if mouseDownUp:
mouseDown(button=button, logScreenshot=False, _pause=False)
mouseDown(button=button, _pause=False)
moveTo(mousex, mousey, duration, tween)
if mouseDownUp:
mouseUp(button=button, logScreenshot=False, _pause=False)
mouseUp(button=button, _pause=False)
def keyDown(key, logScreenshot=None, _pause=True):
def keyDown(key, _pause=True):
global bshift
try:
if len(key) > 1:
@ -555,7 +570,7 @@ def keyDown(key, logScreenshot=None, _pause=True):
pass
def keyUp(key, logScreenshot=None, _pause=True):
def keyUp(key, _pause=True):
global bshift
try:
if len(key) > 1:
@ -573,7 +588,7 @@ def keyUp(key, logScreenshot=None, _pause=True):
pass
def press(keys, presses=1, interval=0.0, logScreenshot=None, _pause=True):
def press(keys, presses=1, interval=0.0, _pause=True):
if type(keys) == str:
if len(keys) > 1:
keys = keys.lower()
@ -594,7 +609,7 @@ def press(keys, presses=1, interval=0.0, logScreenshot=None, _pause=True):
sleep(interval)
def typewrite(message, interval=0.0, logScreenshot=None, _pause=True):
def typewrite(message, interval=0.0, _pause=True):
interval = float(interval) # TODO - this should be taken out.
for c in message:
@ -645,5 +660,7 @@ def screenshot():
if image_path != "":
image = Image.open(image_path)
return image
else:
return None
if __name__ == '__main__':
moveRel(10, 10)

View File

@ -359,6 +359,17 @@ class MouseKey:
cls.press_key_up(c)
sleep(0.03)
@classmethod
def move_to_and_click(cls, _x, _y):
"""
移动到某个位置点击
:param _x: 移动到的位置 x
:param _y: 移动到的位置 y
:return:
"""
cls.move_to(_x, _y)
cls.click()
@classmethod
def move_to_and_right_click(cls, _x, _y):
"""
@ -371,15 +382,15 @@ class MouseKey:
cls.right_click()
@classmethod
def move_to_and_click(cls, _x, _y):
def move_to_and_double_click(cls, _x, _y):
"""
移动到某个位置点击左键
:param _x: 移动到的位置x
:param _y: 移动到的位置y
移动到某个位置点击双击
:param _x: 移动到的位置 x
:param _y: 移动到的位置 y
:return:
"""
cls.move_to(int(_x), int(_y))
cls.click()
cls.move_to(_x, _y)
cls.double_click()
@classmethod
def move_on_and_drag_to(cls, start: tuple, end: tuple):

View File

@ -11,6 +11,10 @@ from setting.globalconfig import GlobalConfig
from src.dbus_utils import DbusUtils
def wf(f, t):
f.write(t.encode("unicode_escape").decode() + "\n")
class AllureReportExtend:
"""AllureReportExtend"""
@ -23,32 +27,39 @@ class AllureReportExtend:
return
if not allure_path:
return
allure_fspath_path = os.path.join(session.config.invocation_dir, allure_path)
with open(
allure_fspath_path + "/environment.properties", "w+", encoding="utf-8"
) as _f:
_f.write(
f"网络地址={GlobalConfig.HOST_IP}".encode("unicode_escape").decode() + "\n"
)
_f.write(
f"系统信息={GlobalConfig.PRODUCT_INFO}".encode("unicode_escape").decode()
+ "\n"
)
_f.write(
f"镜像版本={GlobalConfig.VERSION}".encode("unicode_escape").decode() + "\n"
allure_fspath_path = os.path.join(
session.config.invocation_dir,
allure_path,
"environment.properties"
)
with open(allure_fspath_path, "w+", encoding="utf-8") as _f:
wf(_f, f"网络地址={GlobalConfig.USERNAME}@{GlobalConfig.HOST_IP}")
wf(_f, f"系统信息={GlobalConfig.PRODUCT_INFO}")
wf(_f, f"镜像版本={GlobalConfig.VERSION}")
screen = Tk()
x = screen.winfo_screenwidth()
y = screen.winfo_screenheight()
_f.write(f"分辨率={x}x{y}".encode("unicode_escape").decode() + "\n")
wf(_f, f"分辨率={screen.winfo_screenwidth()}x{screen.winfo_screenheight()}")
try:
language_code = DbusUtils(
"com.deepin.daemon.LangSelector",
"/com/deepin/daemon/LangSelector",
"com.deepin.daemon.LangSelector",
).get_session_properties_value("CurrentLocale")
_f.write(
# pylint: disable=line-too-long
f"系统语言={GlobalConfig.LANGUAGE_INI.get(language_code, default=language_code)}".encode(
"unicode_escape"
).decode()
)
wf(_f, f"系统语言={GlobalConfig.LANGUAGE_INI.get(language_code, default=language_code)}")
except Exception:
pass
_display = GlobalConfig.DisplayServer.wayland if GlobalConfig.IS_WAYLAND else GlobalConfig.DisplayServer.x11
wf(_f, f"显示协议={_display.title()}")
os_info = os.popen("uname -a").read()
wf(_f, f"内核信息={os_info}")
cpu_info = os.popen("cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c").read().replace(" ", "")
if not cpu_info:
cpu_info = os.popen("cat /proc/cpuinfo | grep Hardware").read()
wf(_f, f"CPU信息={cpu_info}")
mem_info = os.popen("cat /proc/meminfo | grep MemTotal").read()
wf(_f, f"内存信息={mem_info}")

View File

@ -61,6 +61,7 @@ class Args(Enum):
build_env = "build_env"
client_password = "client_password"
parallel = "parallel"
autostart = "autostart"
def transform_app_name(real_app_name):

View File

@ -22,14 +22,20 @@ from tkinter import Tk
import pytest
from allure_custom import AllureCustom
from allure_custom.conf import setting
from allure_custom.conf import setting as al_setting
from setting.globalconfig import GetCfg
from setting.globalconfig import GlobalConfig
setting.html_title = GlobalConfig.REPORT_TITLE
setting.report_name = GlobalConfig.REPORT_NAME
setting.report_language = GlobalConfig.REPORT_LANGUAGE
al_setting.html_title = GlobalConfig.REPORT_TITLE
al_setting.report_name = GlobalConfig.REPORT_NAME
al_setting.report_language = GlobalConfig.REPORT_LANGUAGE
from letmego import register_autostart_service
from letmego.conf import setting as letmego_setting
letmego_setting.RUNNING_MAN_FILE = f"{GlobalConfig.REPORT_PATH}/_running_man.txt"
letmego_setting.PROJECT_NAME = GlobalConfig.PASSWORD
from src import logger
from src.rtk._base import Args
@ -77,6 +83,7 @@ class LocalRunner:
build_location=None,
line=None,
exportcsv=None,
autostart=None,
**kwargs,
):
logger("INFO")
@ -112,6 +119,7 @@ class LocalRunner:
if not pms_info_file
else None,
Args.pms_info_file.value: pms_info_file,
Args.autostart.value: autostart or GlobalConfig.AUTOSTART,
}
self.lastfailed = lastfailed
self.project_name = project_name
@ -258,6 +266,8 @@ class LocalRunner:
cmd.append("--duringfail")
if default.get(Args.top.value):
cmd.extend(["--top", default.get(Args.top.value)])
if default.get(Args.autostart.value):
cmd.extend(["--autostart", default.get(Args.autostart.value)])
if default.get(Args.repeat.value):
cmd.extend(["--repeat", default.get(Args.repeat.value)])
if self.line:
@ -335,6 +345,14 @@ class LocalRunner:
system(f"mv {allure_report_path}/* {allure_report_back_path}/")
run_test_cmd = " ".join(run_test_cmd_list)
if self.default.get(Args.autostart.value):
register_autostart_service(
user=GlobalConfig.USERNAME,
working_directory=GlobalConfig.ROOT_DIR,
cmd=run_test_cmd
)
if not self.default.get(Args.pms_info_file.value):
print(f"Running: \n{run_test_cmd}")
if self.default.get(Args.debug.value):

View File

@ -38,7 +38,7 @@ def cli():
youqu_version = conf.get("current", "tag")
except NoSectionError:
youqu_version = None
print(f"The project: [\033[0;32m{project_name}\033[0m],has been created by youqu{f'-{youqu_version}' if youqu_version else ''}.")
print(f"The project: [\033[0;32m{project_name}\033[0m],has been created by youqu{f'-{youqu_version}' if youqu_version else ''}")
if __name__ == '__main__':

View File

@ -72,7 +72,3 @@ class WaylandWindowINfo:
window_info.height
),
}
if __name__ == '__main__':
WaylandWindowINfo().window_info()