youqu/docs/AT经验总结.md

7.4 KiB
Raw Blame History

AT 经验总结

欢迎所有人提交你在自动化测试方面的优秀实践经验,以帮助大家解决可能遇到的问题。

1、终结器

# litaoa@uniontech.com

前置/后置步骤

pytest 实现前置/后置步骤的方式有两种yield 和终结函数;

yield 实现yield前面为用例的前置步骤yield 后面为用例的后置步骤。

@pytest.fixture
def clean_env():
    print("setup")
    yield
    print("teardown")

终结函数实现,使用 request.addfinalizer 注册用例的后置步骤

@pytest.fixture
def clean_env(request):
    def clean():
        print("teardown")
    request.addfinalizer(clean)
    print("setup")

yield的优缺点

优点代码简洁直观可使用yield在用例中获取前置步骤的返回值

缺点:若前置步骤中出现错误,则后置步骤不会执行

终结函数:

优点:前置步骤失败的话,后置步骤仍会执行且可以注册多个后置步骤(前提:需要在代码报错之前注册后置步骤),支持灵活使用后置条件

缺点:代码较为复杂,无法获取前置步骤的返回值(本人目前未实现)

总结在前置步骤保证绝对不会出错时使用yield更佳简便当前置步骤易出现问题时推荐使用终结函数。

场景:保险箱用例,前置步骤中开启保险箱,后置步骤删除保险箱。

@pytest.fixture(scope="session", autouse=True)
def vault_fixture(request):
    DfmWidget.reset_vault_by_cmd()	# 1、重置保险箱
    DdeDockPublicWidget().close_file_manager_by_cmd() # 2、关闭文管
    DdeDockPublicWidget().open_file_manager_in_dock_by_attr() # 3、开启文管
    vault = DfmWidget()
    vault.create_file_vault()	# 4、创建保险箱

    def delete_vault():	# 8、删除保险箱的后置步骤
        sleep(2)
        DdeDockPublicWidget().open_file_manager_in_dock_by_attr()
        vault = DfmWidget()
        vault.delete_file_vault()
        DfmWidget.reset_vault_by_cmd()
        DdeDockPublicWidget().close_file_manager_by_cmd()
    request.addfinalizer(delete_vault)	# 5、注册后置步骤
    DdeDockPublicWidget().close_file_manager_by_cmd()	# 6、关闭文管
    sleep(1)
    DdeDockPublicWidget().open_file_manager_in_dock_by_attr() # 7、开启文管

代码按注释中的序号执行步骤

  • 代码在步骤1-4任意位置报错则不会执行步骤8因为未执行到步骤5步骤8还未注册
  • 代码在步骤6-7报错仍会执行步骤7因为在步骤5中已经将步骤7注册

可以灵活注册后置步骤,能实现某个前置步骤执行之后,才会执行后置步骤。

2、启动应用的方式

# huangmingqiang@uniontech.com

1命令行启动

在 AT 代码中使用命令行启动应用,举例:

os.popen("deepin-music")

这种方式启动存在一个问题,就是当使用 ssh 远程执行用例时,dogtail 无法获取到元素。

2通过 UI 操作启动

通过任务栏、启动器、桌面等UI方式启动比如双击打开、右键打开等这种操作方式不存在ssh 远程执行用例时dogtail 无法获取到元素的问题,也更加符合用户的操作行为。

3、文件选择框属性定位偶现无法找到

文件选择框存在一个问题在调用文件选择框时有一定的概率出现界面已经渲染出来了但是属性树并没有写入导致通过属性无法找到元素目前也没有很好的解决方案为了用例稳定性文件选择框的操作建议使用UI或者图片定位的方式可以通过搜索内容固定文件位置。

# litaoa@uniontech.com
desk = DdeDesktopPublicWidget()
# 选择视频目录
desk.click_videos_dir_in_desktop_plugs_by_ui()
sleep(1)
desk.ctrl_f()
sleep(1)
desk.input_message("元素名称")
sleep(0.5)
desk.enter()
sleep(1)
# 选择第一个文件
desk.click_list_view_btn_in_desktop_plugs_by_ui()
sleep(1)
desk.click_first_file_in_desktop_plugs_by_ui()
sleep(1)
# 文管插件中点击打开
desk.click_open_btn_in_desktop_plugs_by_ui()

4、应用启动

# mikigo

在UI自动化测试中一切操作的都是从应用启动开始的而在Linux桌面应用自动化测试中我们启动应用的方法有多种下面做一个简单的介绍

【使用dogtail启动】

dogtail提供了应用启动的方法在utils库中使用run方法启动

首先导入方法:

from dogtail.utils import *

调用run方法

run('deepin-music')

即可启动音乐 img

这种方法的优点是采用进程的方式直接启动不依赖与UI无论桌面或任务栏上是否存在应用图标都可以正常启动。

但是在实际项目中,仍然存在一个问题,

如果使用ssh远程调用或者Jenkins中执行测试脚本的时候在sniff中会出现找不到应用经过分析可能是因为使用这种方法启动的时候实际是采用一个子进程启动了应用dogtail无法识别到。

【从任务栏启动】

使用dogtail点击任务栏上的应用图标

通常有两种方法:

1使用dogtail点击任务栏上的应用图标。

2已知应用图标在任务栏上的位置然后使用鼠标点击对应坐标。

第二种方法的缺点是位置必须固定,如果移动位置就不行了,而使用第一种方法,无论位置在哪里,只要图标在任务栏上存在即可。

【点击桌面图标启动】

桌面图标目前是采用图像识别技术定位到应用图标的坐标然后通过pyauogui进行点击操作。

详细技术方案可以参考我的另外两篇博客:

基于opencv的模板匹配实现图像识别返回在屏幕中的坐标

Python三方库PyAutoGui的使用方法

【从启动器启动(俗称开始菜单)】

启动中启动的实现逻辑实际和任务栏上启动差不多。

首先需要使用鼠标点击任务栏上的启动器图标或者键盘super键将启动器呼出来

然后,在启动器中点击对应的图标,

但是这里有个问题,启动器中的应用列表,一页展示不完,所以如果我们要点击的应用图标不在第一页怎么办,通常解决方案有两种:

1需要进行向下滑动这里就涉及到相应的识别方案判断如果不在第一页就往下滑动翻页。

2启动器提供搜索的功能输入应用名称搜索然后进行点击。

从实际操作中来看,采用第二种方法的效率会高一点。

【终端命令启动】

在python中使用os.popen()或os.system()或者subprocess.Popen(),实现命令行启动,比如:

import os
os.popen('deepin-music')

这种方式启动是比较简单的但是在实际项目中仍然存在远程执行脚本的时候dogtail无法识别的问题。

【总结】

以上几种方法,各有优缺点,在实际项目中:

1如果需要在Jenkins中做持续集成建议使用第二种任务栏启动的方法。

2如果不会采用远程执行的建议采用第一种或者最后一种方案。

3第三种和第四种启动方法通常在测试用例中会涉及到所以偶尔会用。