【第五篇-完结篇】XiaoZaiMultiAutoAiDevices之改造扩展

简介: 在前面系列文章中有讲到,使用configparser,ini格式的文件作为配置文件,在新增或者删除其中的值时,会丢失所有注释,所以在框架源码注释中我有写到,如果对这方面比较介意或者是有需求的话,可以进行更改配置文件。

【第五篇-完结篇】XiaoZaiMultiAutoAiDevices之改造扩展

这篇是XiaoZaiMultiAutoAiDevices框架系列的最后一篇文章,最后一篇主要讲一下拓展思路

有时候我个人觉得,一个好的解决问题的思路,比花里胡哨的代码强

代码不就是实现解决问题思路的一种手段吗

一、配置文件的拓展

在前面系列文章中有讲到,使用configparserini格式的文件作为配置文件,在新增或者删除其中的值时,会丢失所有注释,所以在框架源码注释中我有写到,如果对这方面比较介意或者是有需求的话,可以进行更改配置文件。

此次扩展仅围绕configparser来,并且只提供思路,后续框架也不会更新(我懒。)

1、如果项目多,可以每个项目建一个文件夹放到TestCase文件下,形成测试用例集

2、在配置文件中新增一个可配置整个文件夹中所有用例的选项(需要更改代码中RunTestCase.py--> 42-58行代码,当前代码是以配置文件中单个py文件来获取的,只需要把判断case文件名的步骤去掉即可。)

3、可以将单个项目作为一个大配置,省去填case文件。

二、测试框架的拓展

RunTestCase中,我只适配了继承ParameterizedTestCase的测试类,我将device_id设置了默认值为None,所以此处应该也兼容直接未继承ParameterizedTestCase的测试类,不过需要使用者进行判断,重新加入suite.addTest()

另外一种可行性方案就是,所有的case类都继承ParameterizedTestCase,因为在ParameterizedTestCase中我继承了unittest.TestCase,默认参数又是None,理论上是没问题的,这个也需要使用者进行尝试调试,我没试(我懒。)

可以将Unittest更换为Pytest,对框架熟悉后,其实可以自己单独写个类似的,到这个框架上改也可以,不过建议自己去尝试写一套,从0到1,你会有很大收获的。

三、测试文件的拓展

可以在外部自己建文件夹,进行一些单独的测试通用类合集,类似于框架中的IOSAppOperate.py

比如我现阶段在公司中,就是使用的这个方法,扩展自己的框架使用范围,兼容自己的项目主要还是靠你的脚本,这个框架只不过是个执行引擎,可以改造的地方非常多。

我习惯性的,建一个项目公共方法目录,再在里面建每个项目下的方法类,如果使用了airtest的图像识别,那么你还可以建一个图片管理文件夹,再创建一个py文件对所有图片进行管理(多个也可以,全凭个人喜好。)

对日志产生的图片或者log,自己也可以进行封装。

四、测试用例的拓展

这一块是关于每个测试case的,在我们正常的case中,一堆if一堆try异常处理一堆assert已经见怪不怪了,但是有个问题,想必是所有做过UI自动化的同学们都痛心疾首的,时间成本。UI耗时,费力,费心是统一认识,但如果说你能解决,那么就是你的一个突破。

在时间问题上,我采用了线程,那么在Unittest中能用线程吗?

答案是可以。

我是怎么实现的?

1、单独创建及封装项目对应模块的代码

2、TestCase中直接导入对应模块类,不写任何冗余代码

3、在封装模块中进行线程的开启关闭操作

示例:

event = threading.Event()
avent = threading.Event()
bvent = threading.Event()
cvent = threading.Event()
dvent = threading.Event()

def themeFunc(n):
    print("主功能点击")
    while True:
        if exists(WS_LIBRARY_img):
            print("点击了LIBRARY图标")
            touch(WS_LIBRARY_img)
        if exists(WS_search_small):
            break
    while True:
        try:
            print("基本功能运行中....")
            # 选择关卡
            if exists(WS_search_small):
                touch(WS_search_small)
            if exists(WS_here_input_text_046):
                touch(WS_here_input_text_046)
                click([0.296, 0.047])
                time.sleep(2)
                text("Big Bad Brother", enter=True)
                time.sleep(3)
            if exists(WS_story_name_img):
                touch(WS_story_name_img)
                break
        except:
            traceback.print_exc()

    ##### 进入小说内容的前置操作
    while True:
        ### 判断重置按钮
        if exists(WS_reset_button_img):
            # play 按钮
            click([0.5, 0.712])
            touch(WS_reset_button_img)
        if exists(WS_reset_story_img):
            touch(WS_reset_story_img)
            time.sleep(2)
            if exists(WS_play_img):
                touch(WS_play_img)
                break

    print("进入多线程阶段开始点击")
    avent.set()
    bvent.set()
    cvent.set()
    dvent.set()
    event.set()

    from threading import Thread
    t1 = Thread(target=theme_game_click_1)
    t2 = Thread(target=theme_game_click_2)
    t3 = Thread(target=time_stop, args=(n,))

    t1.setDaemon(True)
    t1.start()
    t2.setDaemon(True)
    t2.start()
    t3.setDaemon(True)
    t3.start()
    t1.join()
    t2.join()
    t3.join()


def theme_game_click_1():
    #### 这个线程用来点击
    while 1:
        if avent.is_set():
            print("--------第一个------")
            # 中间偏下
            click([0.5, 0.6])
            # 选择衣服的那些
            click([0.5, 0.86])
            # 最终确认
            click([0.5, 0.69])
        else:
            break


def theme_game_click_2():
    ###  这个线程用来关闭spin过程中可能会出现的异常情况
    while 1:
        if bvent.is_set():
            print("--------第二个---------")
            # YES的按钮
            click([0.5, 0.43])
            # 菱形选物体
            click([0.2, 0.585])
            click([0.5, 0.84])
            click([0.5, 0.73])
            # 下一章
            click([0.738, 0.798])
        else:
            break

def time_stop(n):
    print("----启动时间监控-----")
    sleep(60 * n)
    print("---------时间到了,灭霸响指,啪----------")
    avent.clear()
    bvent.clear()
    cvent.clear()
    dvent.clear()
    event.clear()
AI 代码解读

这个就是采用了线程进行点击,并且是可控的。

这个功能主要是去点击一个小说阅读器的阅读功能,验证部分代码涉及敏感信息已经移除。里面的WS开头的是采用的图像识别,直接从封装好的图片库引用的图片名称。

不过这种是属于写脚本了,你可以随意发挥。

到此,完结撒花!

感谢读完本系列的小伙伴 ~

相关文章
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究SpringMVC的核心原理和运作机制(总体框架原理篇)
93 0
手动开发-实现SpringMVC底层机制--小试牛刀
手动开发-实现SpringMVC底层机制--小试牛刀
40 0
从EF6无缝切换到Entity Framework Core:一份详尽无遗的开发者实战攻略,带你领略数据库操作的全新境界,让代码优雅转身,性能与可维护性双丰收的秘密武器
【8月更文挑战第31天】本文通过详细的代码示例,介绍了如何将基于 EF6 的应用程序平滑迁移到 EF Core。从创建初始 EF6 项目并定义数据库上下文开始,逐步演示了如何使用 EF6 进行数据操作。随后,文章详细讲解了迁移到 EF Core 的步骤,包括配置 EF Core 数据库上下文、定义领域模型及数据操作等。通过具体示例,展示了 EF Core 的强大功能,帮助开发者构建高效且可扩展的数据访问层。
108 0
Spring框架的核心原理与应用实践
Spring框架的核心原理与应用实践
构建高性能微服务架构:后端开发的终极指南构建高效Android应用:Kotlin与Jetpack的完美结合
【5月更文挑战第28天】 在现代软件开发的浪潮中,微服务架构已经成为了设计灵活、可扩展且易于维护系统的重要模式。本文将深入探讨如何构建一个高性能的微服务架构,涵盖从基础概念理解到实践策略部署的全过程。我们将讨论关键的设计原则、技术选型、性能优化技巧以及安全性考虑,旨在为后端开发者提供一个全面的指南,帮助他们构建出能够适应快速变化的市场需求和技术挑战的系统。 【5月更文挑战第28天】 在移动开发的世界中,效率和性能是衡量一个应用成功与否的关键因素。本文将深入探讨如何通过结合Kotlin语言和Android Jetpack组件,来构建一个既高效又易维护的Android应用。我们将透过实际案例分析
学习笔记之二《SpringBoot3-核心特性》
学习笔记之二《SpringBoot3-核心特性》
208 0
【第四篇】XiaoZaiMultiAutoAiDevices之核心机制
在上一期说到主要的流程和部分核心运行流程,这一期我们主讲:`如何通过外部参数指定脚本运行指定设备` 测试框架传参,可能一部分同学会想到unittest的DDT,使用pytest相关装饰器和各种外部文件的数据传入方式。
143 0
阐述佛萨奇开发源码 佛萨奇系统开发原力方案 佛萨奇2.0版本源码部署技术解决逻辑
阐述佛萨奇开发源码 佛萨奇系统开发原力方案 佛萨奇2.0版本源码部署技术解决逻辑
149 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等