欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Windows应用自动测试:图片比对功能详解

最编程 2024-02-23 20:36:14
...

windows 应用自动化测试--图像对比

一.原理和框架结构
  1. Sikuli 是通过图像识别在应用的自动化的,完全的黑盒,适用于很多非标准话应用的测试

二.学习成本和业务匹配程度
  1. 框架结构:python+sikulijar包+cv2+jpype+unittest+HTMLTestRunner.py
  2. 业务匹配程度:cpos是非标准win应用,调研发现坐标识识别和图像识别是业界常用的
    方法
  3. 学习成本:很低,截图和调用简单api
  4. 缺点:执行速度相对慢,无法支持跨分辨率,无法提供丰富的断言
  5. 测试结果展示:


    image.png

三.核心api封装
import logging
import os
import time
from jpype import *
from UIlib.logger import Logger
from UIlib import commen
'''
sikuli api封装
'''
loger=Logger('sikuliApi')
class sikuliApi(object):
    def __init__(self):
        self.root_path = os.path.dirname(os.path.split(os.path.realpath(__file__))[0])
        self.pos_type=pos_type
        try:
            sc=JClass("org.sikuli.script.Screen")
            self.Screen = sc()  # 窗口包
            self.Region = JClass("org.sikuli.script.Region")  # 窗口区域识别包
            self.key = JClass("org.sikuli.script.Key")  # 键盘和鼠标操作包
            self.Pattern = JClass('org.sikuli.script.Pattern')  # 识别粒度配置包
            self.FindFailed = JClass('org.sikuli.script.FindFailed')  # 识别异常包
        except Exception as e:
            loger.logger.error("sikuli 包加载错误:{}".format(e))
            exit()

    def d_click(self,img_name,lan,times=0.5,casename=None,is_running=0):
        '''非严格匹配鼠标单击'''
        target_img = self.get_img_path(lan=lan, img_name=img_name)  # 获取图片路径
        try:
            if os.path.exists(target_img) is False:
                loger.logger.error('target_img is not exists:{}'.format(target_img))
            self.Screen.click(target_img)
            time.sleep(times)
    def click(self,img_name,lan,times=0.5,case_name=None,is_running=2,msg=None):
        '''鼠标单击'''
        target_img=self.get_img_path(lan=lan,img_name=img_name)#获取图片路径
        loger.logger.info('点击:{},{}'.format(img_name,msg))
        try:
            if os.path.exists(target_img) is False:
                loger.logger.error('点击的图片不存在:{}'.format(target_img))
            if self.is_exists(img_name=img_name,lan=lan):
                self.Screen.click(self.Pattern(target_img).exact())

            else:
                loger.logger.info('屏幕上没有找到图片:{}'.format(img_name))
            #self.Screen.click(target_img) #宽松模式
            time.sleep(times)
            img_tag=is_running,pos_type=self.pos_type)
        except Exception as e :
            loger.logger.error("click 异常:{}".format(e))

    def double_click(self,lan,img_name,times=0.5,case_name=None,is_running=0):
        '''鼠标双击'''
        target_img = self.get_img_path(lan=lan, img_name=img_name)  # 获取图片路径
        loger.logger.info('点击:{}'.format(img_name))
        try:
            if os.path.exists(target_img) is False:
                loger.logger.error('点击的图片不存在:{}'.format(target_img))
            if self.is_exists(img_name=img_name, lan=lan):
                self.Screen.doubleClick(self.Pattern(target_img).exact())
            else:
                raise Exception('屏幕上没有找到图片:{}'.format(img_name))
            # self.Screen.click(target_img) #宽松模式
            time.sleep(times)
        except Exception as e:
            loger.logger.error("click 异常:{}".format(e))
    def enter_key(self,key='ENTER',times=0.1,casename=None,is_running=0):
        '''键盘操作,暂时未扩展,只支持enter键'''
        loger.logger.info('执行:{}'.format(key))
        try:
            if key=='ENTER':
                self.Screen.type(self.key.ENTER)
            elif key=='backspace':
                self.Screen.type(self.key.BACKSPACE)
            time.sleep(times)
        except Exception as e:
            loger.logger.error("enter_key 异常:{}".format(e))
    def input_str(self,words:str,times=1,casename=None,is_running=0,msg=None):
        '''输入字符串'''
        loger.logger.info('执行输入:{},{}'.format(words,msg))
        try:
            self.Screen.type(str(words))
            time.sleep(times)
            
        except Exception as e:
            loger.logger.error("input_str 异常:{}".format(e))

    def is_exists(self,lan,img_name):
        '''判断图片是否存在'''
        target_img = self.get_img_path(lan=lan, img_name=img_name)  # 获取图片路径
        try:
            if os.path.exists(target_img) is False:
                loger.logger.error('img is not exists:{}'.format(target_img))
            return self.Screen.exists(target_img)
            #return self.Screen.exists(self.Pattern(target_img).exact())
        except Exception as e:
            loger.logger.error("is_exists 异常:{}".format(e))
    def do_screenshots(self,lan,img_name,img_tag=0,is_Shelter=0):
        target_img = self.get_img_path(lan=lan, img_name=img_name)
        if os.path.exists(target_img) is False:
            loger.logger.error('img is not exists:{}'.format(target_img))
        else:
            if  self.is_exists(lan=lan,img_name=img_name):
                commen.get_img(img_name=img_name,img_tag=img_tag,is_Shelter=is_Shelter,pos_type=self.pos_type)
    def wait_until_imgExist(self,img_name,lan,wait_number=20):
        n=1
        while n <wait_number:
            ret=self.is_exists(lan=lan,img_name=img_name)
            loger.logger.info('{} 识别结果:{}'.format(img_name,ret))
            if ret:
                return True
            else:
                loger.logger.info('识别重试:{}'.format(n))
                time.sleep(0.1)
                n=n+1
                if n>=(wait_number-1):
                    loger.logger.info('识别重试结束')
                    return False

    def Switch_screen(self,screen_type):
        ''' 1:大屏幕;0:小屏幕'''
        if screen_type==1:
            Screen = self.Screen.getScreen(1)
        elif screen_type==0:
            Screen = self.Screen.getScreen(0)
        else:
            raise  BaseException('屏幕选择错误:{}'.format(screen_type))
        self.Screen=Screen


if __name__=='__main__':
    pass

    # startdemoVm()
    # api = sikuliApi(pos_type='df')
    # api = sikuliApi(pos_type='df')
    # api.enter_key()
    #
    # shutdoemVm()




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者