【第五篇-完结篇】XiaoZaiMultiAutoAiDevices之改造扩展
这篇是XiaoZaiMultiAutoAiDevices框架系列的最后一篇文章,最后一篇主要讲一下拓展思路有时候我个人觉得,一个好的解决问题的思路,比花里胡哨的代码强
代码不就是实现解决问题思路的一种手段吗
一、配置文件的拓展
在前面系列文章中有讲到,使用configparser,ini格式的文件作为配置文件,在新增或者删除其中的值时,会丢失所有注释,所以在框架源码注释中我有写到,如果对这方面比较介意或者是有需求的话,可以进行更改配置文件。
此次扩展仅围绕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开头的是采用的图像识别,直接从封装好的图片库引用的图片名称。
不过这种是属于写脚本了,你可以随意发挥。
到此,完结撒花!
感谢读完本系列的小伙伴 ~