由于Airtest的Template类中包含了大量的自身框架的内容,所以需要将它拿出来与我们的框架进行整合。
解耦框架部分内容
代码语言:javascript复制from airtest.core.helper import G
在G
中封装了driver
、logger
等对象
我们需要将他变为我们自己的driver
、logger
等对象
from airtest.core.settings import Settings as ST
在Settings
中放了一些常量,变更不大,直接采用硬编码来进行替换
from airtest.core.error import TargetNotFoundError, InvalidMatchingMethodError
重写了几个异常,基本上的操作就是改了个名字,直接拷贝过来就行了
代码语言:javascript复制# 图片比对算法
MATCHING_METHODS = {
"tpl": TemplateMatching,
"mstpl": MultiScaleTemplateMatchingPre,
"gmstpl": MultiScaleTemplateMatching,
"kaze": KAZEMatching,
"brisk": BRISKMatching,
"akaze": AKAZEMatching,
"orb": ORBMatching,
"sift": SIFTMatching,
"surf": SURFMatching,
"brief": BRIEFMatching,
}
这里面是几个图片比对算法,看了一下基本上只需要使用cv
就行了,直接导入使用即可
修改后的文件见
src/utils/picoperator.py
src/utils/error.py
src/utils/cvtools.py
整合入当前框架
在src.utils.elementoperator.ElementOperator._get_locator_tuple
中增加一个定位方式Template
@staticmethod
def _get_locator_tuple(locator):
type_dict = {
"id": By.ID,
"xpath": By.XPATH,
...
"Template": Template
}
locator_t = (type_dict[locator.by_type], locator.element)
return locator_t
修改_get_element
方法,当我们定位使用Template
的时候改变定位方式
if locator_t[0] != Template:
web_element = self.driver.find_element(*locator_t)
else:
web_element = self.loop_find(Template(**eval(locator_t[1])))
见一条yaml中的Template对象
type是Template
value是Template对象的实例化参数
通过Template(**eval(locator_t[1]))
就可以进行解包和入参了
- { desc: "挂号img",type: "Template",value: '{"filename":f"{DATA_PATH}/img/挂号icon.png","record_pos":(-0.356, 0.207),"resolution":(1080, 2400)}',timeout: "10", name: "registered_img" }
封装loop_find
方法:
- 截取当前页面图片
- 使用
match_in
比较图片 - 拿到目标图片在截图的坐标位置
def loop_find(self, query):
file_name = os.path.join(TEST_PIC, f'{str(int(time.time() * 1000))}.png')
self.screenshot_pic(file_name)
screen = imread(file_name)
if screen is None:
logger.warning("截图失败")
else:
match_pos = query.match_in(screen)
if match_pos:
return match_pos
修改click
方法
使用Template
定位拿到的对象是个坐标点,所以使用tap
或者move_by_offset
去操作
if isinstance(ele, tuple):
if isinstance(self.driver, app_webdriver.Remote):
self.driver.tap([ele], 500)
else:
ActionChains(self.driver).move_by_offset(*ele).click().perform()
使用
编写一个测试用例测试一下
代码语言:javascript复制@compose(feature="微医APP", story="首页", title='点击问诊图片')
def test_home_android_click_img(home_android):
"""
点击问诊图片
"""
time.sleep(10)
home_android.click(home_android.registered_img)
print("test")
查看日志打印
代码语言:javascript复制2022-04-07 17:05:32,099| 【DEBUG】| wytest | try match with MultiScaleTemplateMatchingPre
[17:05:32][DEBUG]<airtest.aircv.multiscale_template_matching> [MSTemplatePre] threshold=0.7, result={'result': (135, 1442), 'rectangle': ((44, 1339.56), (44, 1544.56), (227, 1544.56), (227, 1339.56)), 'confidence': 0.4374358654022217}
[17:05:32][DEBUG]<airtest.aircv.utils> find_best_result() run time is 0.12 s.
2022-04-07 17:05:32,220| 【DEBUG】| wytest | try match with TemplateMatching
[17:05:32][DEBUG]<airtest.aircv.template_matching> [Template] threshold=0.7, result={'result': (171, 506), 'rectangle': ((91, 416), (91, 597), (252, 597), (252, 416)), 'confidence': 0.9995594620704651}
[17:05:32][DEBUG]<airtest.aircv.utils> find_best_result() run time is 0.15 s.
2022-04-07 17:05:32,370| 【DEBUG】| wytest | match result: {'result': (171, 506), 'rectangle': ((91, 416), (91, 597), (252, 597), (252, 416)), 'confidence': 0.9995594620704651, 'time': 0.14921331405639648}
发现一个匹配程度为0.9995594620704651
的对象,它的坐标为(171, 506)
https://gitee.com/zx660644/uitest