【第五篇-完结篇】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开头的是采用的图像识别,直接从封装好的图片库引用的图片名称。

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

到此,完结撒花!

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

相关文章
|
4天前
|
设计模式 前端开发 Java
KnowStreaming系列教程第二篇——项目整体架构分析
KnowStreaming系列教程第二篇——项目整体架构分析
48 0
|
3天前
|
资源调度 前端开发 JavaScript
第十章(应用场景篇) Single-SPA微前端架构深度解析与实践教程
第十章(应用场景篇) Single-SPA微前端架构深度解析与实践教程
|
4天前
|
算法 测试技术 数据处理
【C++ 设计思路】优化C++项目:高效解耦库接口的实战指南
【C++ 设计思路】优化C++项目:高效解耦库接口的实战指南
78 5
|
10月前
|
设计模式 安全 Java
基于设计模式改造短信网关服务实战篇(设计思想、方案呈现、源码)
基于设计模式改造短信网关服务实战篇(设计思想、方案呈现、源码)
222 0
|
开发框架 JSON 缓存
从三层架构说起,谈谈对历史项目的小改造
任何框架无论封装的如何优秀,关键还是在于局中 “玩游戏” 的开发者,框架只是提供了基本的开发规则,要大家共同的遵循,这其中最难的就是团队小伙伴达成一致的思维认知和共识。约定由于配置,任何框架不可能面面俱到,过渡设计框架务必会失去部分灵活性(物极必反的道理想必大家都知...
193 1
从三层架构说起,谈谈对历史项目的小改造
|
消息中间件 前端开发 Java
开发中遇到的问题&解决方案(十二)
由于之前做过贷款平台和电商平台,所以对于订单这个东西十分的敏感,有段时间有点疯狂的喜欢逮着京东、淘宝、拼多多的订单页看,思考别人在做的购物车和订单这块是怎么实现的,尝试找找Bug什么的,后面出去面试别人看我的项目也会问一些关于订单如何设计和实现的问题,所以感觉这个东西还是有讲的必要,下面进入主题。
192 0
开发中遇到的问题&解决方案(十二)
|
JSON 运维 前端开发
开发中遇到的问题&解决方案(十一)
前天不是开工嘛,然后刚刚到公司前端说测试环境好像挂了,开工就直接王炸了,找了运维,运维说服务器过年关机了回来发现有个配件坏了,暂时修不好。那我就本地部署一套当测试环境用,我同步了一份生产库到本地,然后问题就来了,之前好好的功能全部出现了问题,因为年前有需求改动,debug了好几遍代码也没有查出问题,然后突然想到MySQL版本不对。
122 0
开发中遇到的问题&解决方案(十一)
|
架构师 前端开发
上篇:技术架构的设计方法
技术思考本质还是结构化思考,所以常见的结构化思考方法也是适用的。这也是大家会看到很多技术架构师都会用一些方法论去分析问题的原因。但这里我不是重新去论述这些常见的技巧,而是分享从技术实战中得到的一些思考方法,为此我分为了技术架构设计的方法和技术 Leader 的思考方法两类。
1023 2
上篇:技术架构的设计方法
|
TensorFlow 算法框架/工具 图计算
如何实现一个图化框架?代码已开源!
大家好,我是不会写代码的纯序员——Chunel Feng[3]。俗话说,人生如码,码如人生。人生中,有些事情是可以同时进行的,有些事情又必须是前后依次进行的;有些事情是可以刚开始就做的,有些事情又必须等待某个时机成熟了才可以开始。
292 0
如何实现一个图化框架?代码已开源!
|
开发框架 .NET 中间件
浅入ABP(1):搭建基础结构的 ABP 解决方案
浅入ABP(1):搭建基础结构的 ABP 解决方案
133 0
浅入ABP(1):搭建基础结构的 ABP 解决方案