16.UI自动化测试框架搭建-添加Template方式定位元素

2022-04-27 09:47:12 浏览数 (1)

由于Airtest的Template类中包含了大量的自身框架的内容,所以需要将它拿出来与我们的框架进行整合。

解耦框架部分内容

代码语言:javascript复制
from airtest.core.helper import G

G中封装了driverlogger等对象

我们需要将他变为我们自己的driverlogger等对象

代码语言:javascript复制
from airtest.core.settings import Settings as ST

Settings中放了一些常量,变更不大,直接采用硬编码来进行替换

代码语言:javascript复制
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

代码语言:javascript复制
@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的时候改变定位方式

代码语言:javascript复制
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]))就可以进行解包和入参了

代码语言:javascript复制
- { 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方法:

  1. 截取当前页面图片
  2. 使用match_in比较图片
  3. 拿到目标图片在截图的坐标位置
代码语言:javascript复制
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去操作

代码语言:javascript复制
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

0 人点赞