airtest图像识别+poco使用实践

Posted 游戏测试技术分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了airtest图像识别+poco使用实践相关的知识,希望对你有一定的参考价值。

airtest图像识别+poco使用实践

前言

最近在学习UI自动化,关于框架的挑选对我来说没啥好挑的,就airtest了,图像识别和接入poco-SDK,公司项目还没有接好SDK,拿网易的提供的demo先来练练手。

安装

我习惯使用python来跑自动化,有些库得安装下 1、airtest

pip install airtest

2、UI自动化框架:poco

pip install poco

3、测试框架:pocounit

pip install pocounit

4、androiddemo下载链接:[1]

先上官网的例子

一、父类

from poco.drivers.unity3d import UnityPocofrom pocounit.case import PocoTestCasefrom pocounit.addons.poco.action_tracking import ActionTrackerclass MyBaseTestCase(PocoTestCase): @classmethod def setUpClass(cls): super(MyBaseTestCase, cls).setUpClass() cls.poco = UnityPoco() # 启用动作捕捉(action tracker) action_tracker = ActionTracker(cls.poco) cls.register_addon(action_tracker)

二、测试用例(继承父类)

# 一个文件里建议就只有一个TestCase# 一个Case做的事情尽量简单,不要把一大串操作都放到一起class MyTestCase(MyBaseTestCase): def setUp(self): # 可以调用一些前置条件指令和预处理指令 pass # 函数名就是这个,用其他名字无效 def runTest(self): '''self.assertEqual相关的断言方法不会收集在测试报告中(网易那边不支持) 要用self.call_airtest.airtest_api.assert_equal相关方法才会收集在测试报告中 ''' # 普通语句跟原来一样 # self.poco(text='角色').click() # 断言语句跟python unittest写法一模一样 # self.assertTrue(self.poco(text='最大生命').wait(3).exists(), "看到了最大生命") # self.poco('btn_close').click() # self.poco('movetouch_panel').offspring('point_img').swipe('up') start_btn = self.poco('btn_start') start_btn.click() time.sleep(0.5) self.assertEqual(start_btn.get_name(),'btn_start',msg='测试一下断言报告') try: self.assertEqual(start_btn.get_name(),'btn_start1',msg='测试一下断言报告 1') except :pass self.try_assert_mothod(self.assertEqual,start_btn.get_name(), 'btn_start1','测试一下断言报告 2') basic_btn = self.poco(text='basic') basic_btn.click([0.5,0.5]) self.try_assert_mothod(self.assertEqual,basic_btn.get_name(),'abc','测试一下断言报告 3') back_button= self.poco('btn_back',type='Button').focus([1,0.1]) back_button.click() if self.poco(text='drag drop').exists(): self.poco(text='drag drop').click() else: back_button.click() def tearDown(self): # 如果没有清场操作,这个函数就不用写出来 pass # 不要写以test开头的函数,除非你知道会发生什么 # def test_xxx(): # passif __name__ in '__main__': pocounit.main() # generate html report time_str = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") simple_report(__file__,output=REPORTPATH/f'test_{time_str}.html',logpath=str(LOGPATH))

实践poco+图像识别

一、封装断言方法

如果正常执行断言方法,失败的话后面的用例会被中断,所以得加上异常兼容;

1、poco的封装

 def poco_assert_mothod(self,func,*args,case_msg=None): ''' :param func: 断言方法 :param args: 断言方法里需要的参数 :return: 返回断言结果 ''' try: if case_msg: return func(*args,msg=case_msg) else: return func(*args) except Exception as e: print(f'{func} ERROR:', e) return False

2、airtest图像识别的封装

 def img_assert_mothod(self,func=None,img_1=None,img_2=None,case_msg='空白说明',threshold=0.8,target_pos=False,rgb=False): ''' :param func: 断言方法,用加括号 :param args: 断言方法里需要的参数 :return: 返回断言结果 ''' ''' Template(r"tpl1532588127987.png", record_pos=(0.779, 0.382), resolution=(407, 264), threshold=0.6, target_pos=5, rgb=False) threshold:识别精准度 target_pos:点击坐标偏移 rgb:色彩识别 示例:assert_not_exists(self.img_template(img), msg) ''' def img_template(img): if not target_pos: return Template(self.img_path + img, threshold=threshold, resolution=self.screen_size, rgb=rgb) else: return Template(self.img_path + img, threshold=threshold, target_pos=target_pos, resolution=self.screen_size, rgb=rgb) try: if case_msg and img_1 and img_2: return func(img_template(img_1),img_template(img_2),case_msg) elif case_msg and (img_1 or img_2): if img_1: return func(img_template(img_1),case_msg) elif img_2: return func(img_template(img_2),case_msg) elif case_msg is False: return func(img_template(img_1)) except Exception as e: print(f'{func} ERROR:', e)

二、给父类添加ADB的方法

class MyBaseTestCase(PocoTestCase): @classmethod def setUpClass(cls): super(MyBaseTestCase, cls).setUpClass() cls.poco = UnityPoco() # 启用动作捕捉(action tracker) action_tracker = ActionTracker(cls.poco) cls.register_addon(action_tracker) self.img_ath = None # AdbShell在之前的的文章里可以找到,封装常用的adb命令 self.adb = AdbShell() self.task_id = None if self.check_devices(): self.screen_size = self.adb.get_screen_size() # demo游戏包名 self.app_name = 'com.NetEase' self.app = self.adb.get_thirdparty_app(filter=self.app_name) else:raise ConnectionError # 获取操作系统 self.system = os.name def check_devices(self): if self.adb.getDevices() is not False: return True else: self.adb.adb('adb kill-server') self.adb.adb('adb start-server')

三、poco常用方法

 def __doc__(self): '''选择UI对象''' self.poco('') # select by node name self.poco('bg_mission') # select by name and other properties self.poco('bg_mission', type='Button') self.poco(textMatches='^据点.*$', type='Button', enable=True) #加上对应属性来定位 # select by direct child/offspring self.poco('main_node').child('list_item').offspring('item') # 顺序选择 items = self.poco('main_node').child('list_item').offspring('item') print(items[0].child('material_name').get_text()) # 迭代遍历一组UI items = self.poco('main_node').child('list_item').offspring('item') for item in items: item.child('icn_item') '''读取属性''' mission_btn = self.poco('bg_mission') print(mission_btn.attr('type')) # 'Button' print(mission_btn.get_text()) # '获取text' print(mission_btn.attr('text')) # equivalent to .get_text() print(mission_btn.exists()) # True/False, exists in the screen or not '''操作UI对象''' # 点击 self.poco('bg_mission').click() self.poco('bg_mission').click('center') self.poco('bg_mission').click([0.5, 0.5]) # equivalent to center self.poco('bg_mission').focus([0.5, 0.5]).click() # equivalent to above expression self.poco() # 滑动 joystick = self.poco('movetouch_panel').child('point_img') joystick.swipe('up') joystick.swipe([0.2, -0.2]) # swipe sqrt(0.08) unit distance at 45 degree angle up-and-right joystick.swipe([0.2, -0.2], duration=0.5) # 拖拽 self.poco(text='突破芯片').drag_to(self.poco(text='岩石司康饼')) # 等待 self.poco('bg_mission').wait(5).click() # wait 5 seconds at most,click once the object appears self.poco('bg_mission').wait(5).exists() # wait 5 seconds at most,return Exists or Not Exists self.poco().wait_for_appearance() # 等待目标出现,超时raises PocoTargetTimeout self.poco().wait_for_disappearance() # 等待目标消失,超时raises PocoTargetTimeout # self.poco.wait_for_any() # self.poco.wait_for_all() '''全局操作''' # 点击 self.poco.click([0.5, 0.5]) # click the center of screen self.poco.long_click([0.5, 0.5], duration=3) # swipe from A to B point_a = [0.1, 0.1] center = [0.5, 0.5] self.poco.swipe(point_a, center) # 滑动 direction = [0.1, 0] self.poco.swipe(point_a, direction=direction) # 截屏 from base64 import b64decode b64img, fmt = self.poco.snapshot(width=720) open('screen.{}'.format(fmt), 'wb').write(b64decode(b64img))

四、商店测试用例

SDK还没有接好,目前是用图像识别的方式写个demo

class TestShop(MyBaseTestCase): ''' 用例设计参考思维导图的测试用例 ''' def setUp(self): self.call_airtest.img_path = Path(__file__).parent / 'imgFolder' def close_tips(self): tips_1 = self.call_airtest.img_assert_mothod(exists,'goods_tips_close_btn.png',case_msg=False) tips_2 = self.call_airtest.img_assert_mothod(exists,'rank_close_btn.png',target_pos=3,case_msg=False) if tips_1: touch(tips_1) if tips_2: touch(tips_2) def runTest(self): self.close_tips() '''用例执行方法在这里''' self.entrance('shop_icon_1.png', 'shop_icon_2.png', 'shop_homepage.png') self.shop_type('yuanbao_shop.png', 'duihuan_shop.png','jipin_shop.png','jifen_shop.png') self.title('shop_tag_1.png','shop_tag_2.png','shop_tag_3.png') # 购买多个商品,图片坐标偏移8 shop_goods_list = [ ('银两','yinliang.png','yinliang_max.png',5), ('福袋碎片','fudai.png','fudai_max.png',1), ('5级宝石', 'baoshi5.png', 'baoshi5_max.png', 5), ('兽丹礼包', 'shoudan.png', 'shoudan_max.png', 5), ] for test_data in shop_goods_list: self.gold_daily_shop(*test_data) def tearDown(self): # 如果没有清场操作,这个函数就不用写出来 pass # 判断入口 def entrance(self,enter_img_1=None,enter_img_2=None,shop_homepage=None): shop_icon = self.call_airtest.img_assert_mothod(assert_exists,enter_img_1,case_msg='显示商店图标') if shop_icon: touch(shop_icon) sleep(1.5) self.call_airtest.img_assert_mothod(assert_exists,shop_homepage,case_msg='进入后出现商品页签') else: wait_shop_icon = wait(Template(self.call_airtest.img_path+enter_img_2),5) if wait_shop_icon: touch(wait_shop_icon) self.call_airtest.img_assert_mothod(assert_exists,shop_homepage,case_msg='进入后出现商品主页') else: raise TargetNotFoundError def shop_type(self,type_1,type_2,type_3,type_4): '''各个商城''' self.shop_type_1 = self.call_airtest.img_assert_mothod(assert_exists,type_1,case_msg='显示元宝商城') self.shop_type_2 = self.call_airtest.img_assert_mothod(assert_exists,type_2,case_msg='显示兑换商城') self.shop_type_3 = self.call_airtest.img_assert_mothod(assert_exists,type_3,case_msg='显示极品商城') self.shop_type_4 = self.call_airtest.img_assert_mothod(assert_exists,type_4,case_msg='显示积分商城') def title(self,shop_tag_1,shop_tag_2,shop_tag_3): '''页签''' self.shop_tag_1 = self.call_airtest.img_assert_mothod(assert_exists,shop_tag_1,case_msg='显示每日特惠页签') self.shop_tag_2 = self.call_airtest.img_assert_mothod(assert_exists,shop_tag_2,case_msg='显示常用道具页签') self.shop_tag_3 = self.call_airtest.img_assert_mothod(assert_exists,shop_tag_3,case_msg='显示特权商城页签') def gold_daily_shop(self,goods,goods_img,goods_max_img,buy_max): '''商店购买''' # 点击元宝商城 if self.shop_type_1: touch(self.shop_type_1) # 点击每日特惠 if self.shop_tag_1: touch(self.shop_tag_1) else: print('入口目标没有找到,调整截图或降低识别率') raise TargetNotFoundError # self.call_airtest.img_assert_mothod(assert_exists,cost_img,case_msg=f'{goods}道具价格') # 商品 self.goods_pos = self.call_airtest.img_assert_mothod(assert_exists,goods_img,target_pos=8,case_msg=f'显示{goods}道具') # swipe(self.goods_pos,vector=(0.5,0.8)) if self.goods_pos: # 限购 for i in range(buy_max): touch(self.goods_pos) # 滑动到底部 # 滑动一次接近翻一页 self.swipe_up_pos = (520,1910),(520,607) swipe(*self.swipe_up_pos) swipe(*self.swipe_up_pos) sleep(1) self.goods_max_pos = self.call_airtest.img_assert_mothod(assert_exists,goods_max_img,case_msg=f'{goods}购买{buy_max}次后,达到上限灰化') # 划回去 self.swipe_down_pos = (520,607),(520,1910) swipe(*self.swipe_down_pos) swipe(*self.swipe_down_pos) sleep(1)

结语

UI自动化这块我接触的少,经验也不足,属于摸索起步阶段,据了解目前多数同行都应用于回归测试,向他们请教怎么应用,后续有好的应用方法再更新上来,有好的建议欢迎留言,感谢。

微信二维码

引用链接

[1] 下载链接:: http://top.gdl.netease.com/poco-res/poco-demo-unity-game-android.zip


以上是关于airtest图像识别+poco使用实践的主要内容,如果未能解决你的问题,请参考以下文章

Airtest简单介绍

UI 自动化找元素太难?AIRtest 框架你值得拥有!

基于图像识别框架Airtest的Windows项目自动化测试实践

基于Airtest实现python自动抢红包

Airtest环境搭建及介绍

Airtest基于图像识别的自动化测试工具