【第五篇-完结篇】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()

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

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

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

到此,完结撒花!

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

相关文章
|
3月前
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
511 68
|
5月前
|
数据库 开发者
从EF6无缝切换到Entity Framework Core:一份详尽无遗的开发者实战攻略,带你领略数据库操作的全新境界,让代码优雅转身,性能与可维护性双丰收的秘密武器
【8月更文挑战第31天】本文通过详细的代码示例,介绍了如何将基于 EF6 的应用程序平滑迁移到 EF Core。从创建初始 EF6 项目并定义数据库上下文开始,逐步演示了如何使用 EF6 进行数据操作。随后,文章详细讲解了迁移到 EF Core 的步骤,包括配置 EF Core 数据库上下文、定义领域模型及数据操作等。通过具体示例,展示了 EF Core 的强大功能,帮助开发者构建高效且可扩展的数据访问层。
72 0
|
5月前
|
Dubbo Java Nacos
【实战攻略】破解Dubbo+Nacos+Spring Boot 3 Native打包后运行异常的终极秘籍——从零开始彻底攻克那些让你头疼不已的技术难题!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但使用Dubbo+Nacos+Spring Boot 3进行GraalVM native打包后常遇运行异常。本文剖析此问题及其解决策略:确认GraalVM版本兼容性;配置反射列表以支持必要类和方法;采用静态代理替代动态代理;检查并调整配置文件;禁用不支持的功能;利用日志和GraalVM诊断工具定位问题;根据诊断结果调整GraalVM配置。通过系统排查方法,能有效解决此类问题,确保服务稳定运行。
137 0
|
8月前
|
监控 负载均衡 Dubbo
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
134 0
|
8月前
|
Java 双11 Docker
真香!覆盖全网的微服务架构笔记,看完还不懂你来打我
在这个凡事皆互联的时代,越来越多的人和物成为互联网上的节点,不断扩充着互联网这张大网的边界。节点即价值,更多的节点意味着更大的价值。
|
前端开发 Java 关系型数据库
IT市场寒冬过了!GitHub置顶的Spring微服务架构实战派手册有用了
“今年找工作好难啊” 感觉大家总是陷入市场寒冬这个氛围里面“无法自拔”,虽然今年经济下行,工作的确难找,但是在职友集上可查询到的Java岗位仍有20w+,需求相比其他而言并不算少,更别提还有技术细分下的岗位可选!
|
缓存 监控 Java
从零到一构建完整知识体系,阿里最新SpringBoot原理最佳实践真香
Spring Boot不用多说,是咱们Java程序员必须熟练掌握的基本技能。工作上它让配置、代码编写、部署和监控都更简单,面试时互联网企业招聘对于Spring Boot这个系统开发的首选框架也是考察的比较严苛,如果你不是刚入行,只是停留在会用的阶段,那是远远不够的。 虽然Spring Boot易上手,但很多小伙伴也是时不时会跟我反映,Spring Boot技术体系太庞杂了,包含了太多的技术组件,不知道到底该如何高效学习,建立起全面且完整的Spring Boot技术体系和实践技巧,这个时候站在巨人的肩膀上学习就变得非常有必要了,汲取大佬们的学习经验,避免工作面试踩坑,轻松构建Spring Bo
|
消息中间件 Cloud Native Java
【深入浅出SpringCloud原理及实战】「SpringCloud-Alibaba系列」微服务模式搭建系统基础架构实战指南及版本规划踩坑分析
【深入浅出SpringCloud原理及实战】「SpringCloud-Alibaba系列」微服务模式搭建系统基础架构实战指南及版本规划踩坑分析
729 1
【深入浅出SpringCloud原理及实战】「SpringCloud-Alibaba系列」微服务模式搭建系统基础架构实战指南及版本规划踩坑分析
|
XML 存储 缓存
从MessageSource源码出发实战spring·i18n国际化的三种改造方案
从源码去看MessageSource的几个实现类的源码出发,基于spring的国际化支持,实现国际化的开箱即用,静态文件配置刷新生效以及全局异常国际化处理。
749 0
从MessageSource源码出发实战spring·i18n国际化的三种改造方案
|
架构师 前端开发
上篇:技术架构的设计方法
技术思考本质还是结构化思考,所以常见的结构化思考方法也是适用的。这也是大家会看到很多技术架构师都会用一些方法论去分析问题的原因。但这里我不是重新去论述这些常见的技巧,而是分享从技术实战中得到的一些思考方法,为此我分为了技术架构设计的方法和技术 Leader 的思考方法两类。
1120 10
上篇:技术架构的设计方法