def compare_img(self, locator, expect_img, res=5): """ 比较两张图片相识度 :param locator: :param expect_img: :return: """ if isinstance(locator, tuple): ac_img = self.screen_ele_shot(locator) else: ac_img = locator ac_hash = util.pHash(ac_img) if self.platform == 'ios': expect_img = '{}/src/images/ios_eleimg/{}.png'.format( base_path.get_path(), expect_img) elif self.platform == 'android': expect_img = '{}/src/images/android_eleimg/{}.png'.format( base_path.get_path(), expect_img) expect_hash = util.pHash(expect_img) _res = util.cmpHash(ac_hash, expect_hash) os.remove(ac_img) if _res <= res: return True else: return False
def get_image_point(self, path): ''' 查找图片元素坐标 :param path:目标图片 :return: ''' # 目标控件的截图 find_img = cv2.imread(path) # 目标截图 # 对当前屏幕进行截图 img_path = '{}/src/images/click_image.png'.format(base_path.get_path()) self.driver.get_screenshot_as_file(img_path) # 当前屏幕截图 target_img = cv2.imread(path) # 在当前屏幕的截图上进行横向和纵向比对,查找目标控件 result = cv2.matchTemplate(target_img, find_img, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # 如果相似度最高的位置,相似度达到99.9%,说明已经找到了目标控件 if max_val > 0.999: find_height, find_width, find_channel = find_img.shape[::] width = self.driver.get_window_size()['width'] multiple = find_width / width # 算出倍数 x = max_loc[0] + int(find_width * 0.5) # 像素点 x = int(x / multiple) # 坐标点 y = max_loc[1] + int(find_height * 0.5) # 像素点 y = int(y / multiple) # 坐标点 return x, y else: raise Exception('Not Found Image Element')
def appium_setup(request): """ 启动appium服务 :param request: :return: """ global device_sn, pf, server_ip, appium_port, appium_log_path, device_name, platform_version, wda_port, system_port, appium_p device_sn = cmd_sn(request) # 从执行命令读取测试手机sn号 pf = cmd_platform(request).lower() GlobalVar.set_add_remove(cmd_remove_add(request)) appium_port = util.create_port(server_ip, 4723, 7999) appium_log_path = "{}/src/appium_log/{}_{}.log".format(base_path.get_path(), datetime.now().strftime('%Y-%m-%d_%H.%M.%S'), appium_port) if pf == 'ios': GlobalVar.set_platform(GlobalVar.IOS) # 将平台名保存成全局的变量,脚本中通过GlobalVar.get_platform()获取当前执行的平台 # device_name = util.get_iphone_name(device_sn) device_name = 'iPhone eufy' platform_version = util.get_iphone_version(device_sn) wda_port = util.create_port(server_ip, 8100, 9999) appium_p = subprocess.Popen( "appium -a {} -p {} --webdriveragent-port {} --relaxed-security --session-override > {} 2>&1 &".format (server_ip, appium_port, wda_port, appium_log_path), shell=True) # 命令行启动appium服务 elif pf == 'android': GlobalVar.set_platform(GlobalVar.ANDROID) # 将平台名保存成全局的变量,脚本中通过GlobalVar.get_platform()获取当前执行的平台 util.uninstall_uiautomator2_server() # 卸载手机上安装的uiautomator2 server两个app system_port = util.create_port(server_ip, 8200, 8299) appium_p = subprocess.Popen( "appium -a {} -p {} --relaxed-security --session-override > {} 2>&1 &" .format(server_ip, appium_port, appium_log_path), shell=True) # 命令行启动appium服务 else: raise EnvironmentError('设备平台类型传参错误:--cmd_pf='+pf) time.sleep(10) # 新测试报告 global rp_logger rp_logger = logging.getLogger(__name__) rp_logger.setLevel(logging.DEBUG) # Create handler for Report Portal if the service has been # configured and started. if hasattr(request.node.config, 'py_test_service'): # Import Report Portal logger and handler to the test module. logging.setLoggerClass(RPLogger) rp_handler = RPLogHandler(request.node.config.py_test_service) # Add additional handlers if it is necessary console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(logging.INFO) rp_logger.addHandler(console_handler) else: rp_handler = logging.StreamHandler(sys.stdout) # Set INFO level for Report Portal handler. rp_handler.setLevel(logging.INFO) GlobalVar.set_rp_logger(rp_logger) def teardown(): try: os.killpg(os.getegid(appium_p.pid+1), signal.SiGTERM) except Exception as e: print(e) pass request.addfinalizer(teardown)
def read_local_app_version(pf): version = 'none' with open('{}/version.txt'.format(base_path.get_path())) as f: for line in f: if pf in line.strip(): version = line.strip().split('=')[1] break return version
def __init__(self, path=None): if path: config_path = path else: root_dir = base_path.get_path() config_path = os.path.join(root_dir, 'src/config/config.ini') self.cf = configparser.ConfigParser() self.cf.read(config_path)
def read_json(self, param): """ 读取json文件 :return: """ path = '{}/src/config/helplist.json'.format(base_path.get_path()) with open(path, 'r') as load_f: load_dict = json.load(load_f) return load_dict[param]['titles']
def make_path(): ''' 创建保存失败截图的文件目录 :param nodeid: :return: ''' path = '{}/result_images'.format(base_path.get_path()) if not os.path.exists(path): os.makedirs(path) return path
def screen_ele_shot(self, locator): """ 截取元素图片 :return: """ if isinstance(locator, tuple): ele = self.get_element(locator) else: ele = locator path = '{}/src/images/ele.png'.format(base_path.get_path()) ele.screenshot(path) return path
def is_colorful(self, locator): ''' 控件颜色是不是彩色的,可以用于判断开关是否打开,设备是否在线等 :param locator: :return: ''' if isinstance(locator, tuple): el = self.get_element(locator) else: el = locator path = '{}/src/images/click_image.png'.format(base_path.get_path()) el.screenshot(path) (r, g, b) = self.image_color(path) if abs(r - g) <= 3 and abs(g - b) <= 3 and abs( r - b) <= 3: # 灰r=g=b,白r=g=b=255,黑r=g=b=0 return False else: return True
def image_is_exists(self, path, timeout=60): ''' 图片所对应的控件是否存在 :param path:目标图片 :param timeout: :return: ''' # 目标控件的截图 find_img = cv2.imread(path) # 目标截图 img_path = '{}/src/images/click_image.png'.format(base_path.get_path()) for i in range(timeout): # 对当前屏幕进行截图 self.driver.get_screenshot_as_file(img_path) # 当前屏幕截图 target_img = cv2.imread(path) # 在当前屏幕的截图上进行横向和纵向比对,查找目标控件 result = cv2.matchTemplate(target_img, find_img, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # 如果相似度最高的位置,相似度达到99.9%,说明已经找到了目标控件 if max_val > 0.999: return True else: time.sleep(5) return False
import time from datetime import datetime from email.mime.text import MIMEText from email.header import Header import base_path # 第三方 SMTP 服务 mail_host = "smtp.gmail.com" #设置服务器 mail_user = "******" #用户名 sender = '*****@*****.**' receivers = ['*****@*****.**', '*****@*****.**', '*****@*****.**'] cc_mail = [] # receivers = ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**'] # 接收邮件 # cc_mail = ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**'] # 抄送 dst_file_path = '{}/apppackage/'.format(base_path.get_path()) # 本地目录 path = '{}/suites.csv'.format(base_path.get_path()) # 报告的html <a href="http://10.1.54.233:8890/appliance/${platfrom}/${build_time}/index.html">${platfrom}测试报告</a> mail_msg = '''<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>接口测试报告</title> <style type="text/css"> html,body,table,thead,tbody,tr,th,td,caption { margin: 0; padding: 0; }
# -*- coding:utf-8 -*- import os import subprocess import base_path import argparse from ftplib import FTP pf = '' ftp_ip = "10.1.54.233" ftp_username = "******" ftp_pwd = "123456" ftp_android_path = "/09_CI-APP/Appliance/eufyhome_android/" # FTP目录 ftp_ios_path = "/09_CI-APP/Appliance/eufyhome_ios/" # FTP目录 dst_file_path = '{}/apppackage/'.format(base_path.get_path()) # 本地目录 def get_app_version(sn): if pf == 'ios': p = subprocess.Popen( "ideviceinstaller -u {} -l | grep EufyHome".format(sn), shell=True, stdout=subprocess.PIPE) p.wait() out, err = p.communicate() app_version = str(out).replace('"', '').split(',')[1] if pf == 'android': p = subprocess.Popen( 'adb -s {} shell dumpsys package com.eufylife.smarthome'.format( sn), shell=True,
def add_check_image(self, desc): name = datetime.now().strftime('%m%d%H%M%S') path_name = u'{}/result_images/{}.png'.format(base_path.get_path(), name) self.screen_shot(path_name) allure.attach.file(path_name, "【" + desc + " checkpoint截图:{}.png】".format(name), allure.attachment_type.PNG)