def get_config(path): """ 用来格式化打印日志到文件和控制台 :param path:配置文件路径 :return:返回配置文件dict """ global config # 重新获取时,先清空配置 config.clear() txt = Txt(path) data = txt.read() for s in data: # 跳过注释 if s.startswith('#'): continue if not s.find('=') > 0: logger.warn('配置文件格式错误,请检查:' + str(s)) continue try: key = s[0:s.find('=')] value = s[s.find('=') + 1:s.__len__()] config[key] = value except Exception as e: logger.warn('配置文件格式错误,请检查:' + str(s)) logger.exception(e) return config
def send(self, text): # 这里使用SMTP_SSL就是默认使用465端口,如果发送失败,可以使用587 smtp = SMTP_SSL(self.mail_info['hostname']) smtp.set_debuglevel(0) ''' SMTP 'ehlo' command. Hostname to send for this command defaults to the FQDN of the local host. ''' smtp.ehlo(self.mail_info['hostname']) smtp.login(self.mail_info['username'], self.mail_info['password']) # 普通HTML邮件 # msg = MIMEText(text, 'html', self.mail_info['mail_encoding']) # 支持附件的邮件 msg = MIMEMultipart() msg.attach(MIMEText(text, 'html', self.mail_info['mail_encoding'])) msg['Subject'] = Header(self.mail_info['mail_subject'], self.mail_info['mail_encoding']) # msg['from'] = self.mail_info['from'] # 添加自定义昵称 h = Header(self.mail_info['mailnick'], 'utf-8') h.append('<' + self.mail_info['from'] + '>', 'ascii') msg["from"] = h # logger.debug(self.mail_info) # logger.debug(text) msg['to'] = ','.join(self.mail_info['to']) msg['cc'] = ','.join(self.mail_info['cc']) receive = self.mail_info['to'] receive += self.mail_info['cc'] # 添加附件 for i in range(len(self.mail_info['filepaths'])): att1 = MIMEText( open(self.mail_info['filepaths'][i], 'rb').read(), 'base64', 'utf-8') att1['Content-Type'] = 'application/octet-stream' # att1['Content-Disposition'] = 'attachment; filename= "'+self.mail_info['filenames'][i]+'"' att1.add_header('Content-Disposition', 'attachment', filename=('gbk', '', self.mail_info['filenames'][i])) msg.attach(att1) try: smtp.sendmail(self.mail_info['from'], receive, msg.as_string()) smtp.quit() logger.info('邮件发送成功') except Exception as e: logger.error('邮件发送失败:') logger.exception(e)
def callmethod(self, path, params): """ 以列表形式传webservice接口参数 :param path: 接口名 :param params: 参数 :return: 成功失败 """ # 实现关联 params = self.__get__relations(params) # 对传入参数的处理 if params is None or params == '': params = None else: params = self.__get_list(params) # 对path进行处理 if path is None or path == '': # 接口地址不应该为空 self.__write_excel(False, "接口名字错误") return False # 处理url连接失败的情况 try: if params is None: self.result = self.client.service.__getattr__(path)() else: self.result = self.client.service.__getattr__(path)(*params) except Exception as e: logger.exception(e) self.result = None print(self.result) try: # 如果返回的是json字符串,就处理为字典 resulttext = self.result resulttext = resulttext[resulttext. find('{'):resulttext.rfind('}') + 1] self.jsonres = json.loads(resulttext) self.__write_excel(True, self.jsonres) except Exception as e: logger.exception(e) self.jsonres = None if self.result is None: self.__write_excel(False, None) else: self.__write_excel(True, self.result) return True
def post(self, path, params): """ 以data字典形式传键值对参数 :param path: 接口地址 :param params: 参数字典 :return: 成功失败 """ # 对传入参数的处理 if params is None or params == '': params = None # 对path进行处理 if path is None or path == '': # 接口地址不应该为空 self.__write_excel(False, "接口名字错误") return False # 实现关联 params = self.__get__relations(params) params = self.__use_encrypt(params) params = self.__get_data(params) # 如果传非绝对路径的地址,就拼上基础地址 if not path.startswith("http"): path = self.url + "/" + path # 处理url连接失败的情况 try: self.result = self.session.post(path, data=params) except Exception as e: self.result = None try: # 如果返回的是json字符串,就处理为字典 resulttext = self.result.text resulttext = resulttext[resulttext. find('{'):resulttext.rfind('}') + 1] self.jsonres = json.loads(resulttext) self.__write_excel(True, self.jsonres) print(str(self.jsonres)) except Exception as e: logger.exception(e) print(self.result.text) print(str(traceback.format_exc())) self.jsonres = None if self.result is None: self.__write_excel(False, None) else: self.__write_excel(True, self.result.text) return True
def geturl(self, url): """ 打开网站 :param url: 输入网站 :return: 打开成功/失败 """ if self.driver is None: self.__write_excel(False, "浏览器不存在") return False try: self.driver.get(url) self.__write_excel(True, "访问地址成功") return True except Exception as e: self.__write_excel(False, "访问地址失败") logger.exception(e) return False
def addheader(self, key, value): """ 往请求头里面添加一个键值对 :param key: 头的键 :param value: 头的值 :return: 成功失败 """ value = self.__get__relations(value) self.headers[key] = value # 创建一个客户端去请求服务器 try: self.client = Client(self.wsdl, headers=self.headers) self.__write_excel(True, self.headers) except Exception as e: logger.exception(e) self.__write_excel(False, traceback.format_exc()) return False return True
def setwsdl(self, url): """ 设置项目接口基本地址 :param url: wsdl文档地址 :return: 成功失败 """ # 对传入参数的处理 if url is None or url == '': url = '' self.wsdl = url # 创建一个客户端去请求服务器 try: self.client = Client(self.wsdl) self.__write_excel(True, self.wsdl) except Exception as e: logger.exception(e) self.__write_excel(False, traceback.format_exc()) return False return True
def removeheader(self, key): """ 从请求头删除一个键值对 :param key: 需要删除的键 :return: 成功失败 """ try: self.headers.pop(key) except Exception as e: pass # 创建一个客户端去请求服务器 try: self.client = Client(self.wsdl, headers=self.headers) self.__write_excel(True, self.headers) except Exception as e: logger.exception(e) self.__write_excel(False, traceback.format_exc()) return False return True
def __init__(self): # 配置mysql参数 self.mysql_config = { 'mysqluser': "******", 'mysqlpassword': "******", 'mysqlport': 3306, 'mysqlhost': 'localhost', 'mysqldb': 'test_project', 'mysqlcharset': "utf8" } # 从配置文件读取配置 for key in self.mysql_config: try: self.mysql_config[key] = config.config[key] except Exception as e: logger.exception(e) # 把端口处理为整数 try: self.mysql_config['mysqlport'] = int( self.mysql_config['mysqlport']) except Exception as e: logger.exception(e)
def get_res(self, result_path): # 用于记录执行结果,逻辑为,只要分组中出现一个失败用例,则认为该分组执行失败,与flag联合使用。 self.sumarry.clear() status = "Fail" # 标识是否有失败 flag = True # 统计测试用例集的用例总条数 totalcount = 0 # 统计所有用例中通过用例的条数数 totalpass = 0 reader = Reader() reader.open_excel(result_path) reader.readline() line = reader.readline()[1] print(line) self.sumarry['runtype'] = line[1] self.sumarry['title'] = line[2] self.sumarry['starttime'] = line[3] self.sumarry['endtime'] = line[4] # 获取所有sheet页面 for n in reader.get_sheets(): # logger.info(n) # 从第一个页面开始解析 reader.set_sheet(n) # 获取sheet的行数,用来遍历 row = reader.rows # 设置从第二行开始读 reader.r = 1 # 遍历sheet里面所有用例 # openpyxl lines = reader.readline() for i in range(1, row): # line = reader.readline() line = lines[i] # logger.info(line) # 查找记录了分组信息的行 # 如果第一列(分组信息)和第二列(类别或用例名)不同时为空,则不是用例,执行非用例的操作 if not (line[0] == '' and line[1] == ''): pass # 非用例行判断结束 # 第一列信息和第二列信息均为空的行,即用例行,这时开始进行用例数、通过数、状态的统计。 else: # 判断执行结果列,如果为空,将flag置为false,视为该行有误,不纳入用例数量计算 if len(line) < 8 or line[7] == '': flag = False # 执行结果不为空,则将用例统计数自增 else: totalcount = totalcount + 1 # logger.info(line) # 如果通过,则通过数和总通过数均自增 if line[7] == "PASS": totalpass += 1 else: # 出现了用例执行结果不是PASS的情况,则视为当前分组执行失败。 flag = False # for循环结束 # 所有用例执行概况 # logger.info(totalpass) # 计算执行通过率 if flag: status = "Pass" # 计算通过率 try: p = int(totalpass * 10000 / totalcount) passrate = p / 100 except Exception as e: passrate = 0.0 logger.exception(e) # 用例总数 self.sumarry["casecount"] = str(totalcount) # 通过率 self.sumarry["passrate"] = str(passrate) self.sumarry['status'] = status # logger.info(self.sumarry) return self.sumarry
def openbrowser(self, br="gc", ex=""): """ 打开浏览器 :param br: gc=谷歌浏览器(默认);ff=火狐浏览器;ie=ie浏览器 :param ex: 对应driver的路径,默认在项目的lib目录 :return: 打开成功失败 """ try: if br is None or br == "gc" or br == "": # 使用用户文件加载缓存和配置chrome的安装路径 # 创建一个chrome的配置项对象 option = webdriver.ChromeOptions() # 获取用户文件路径 userfile = os.environ["USERPROFILE"] # 添加用户文件配置 # 使用缓存,也使用了cookie option.add_argument( "--user-data-dir=%s\\AppData\\Local\\Google\\Chrome\\user data" % userfile) # 配置chrome安装路径 # option.binary_location = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" # 打开浏览器 # driver就相当于打开的浏览器 if ex == "": ex = "./lib/conf/chromedriver.exe" self.driver = webdriver.Chrome(options=option, executable_path=ex) elif br == 'ff': if ex == "": ex = "./lib/conf/geckodriver.exe" # 有cookie的,但是缓存不存在,所以加载还是比较慢 # 使用cmd命令去创建一个用户文件 # "C:\Program Files\Mozilla Firefox\firefox.exe" -p opt = webdriver.FirefoxOptions() opt.profile = r'%s\AppData\Roaming\Mozilla\Firefox\Profiles\mytest.mytest' % os.environ[ "USERPROFILE"] self.driver = webdriver.Firefox(executable_path=ex, firefox_options=opt) elif br == 'ie': if ex == "": ex = "./lib/conf/IEDriverServer.exe" opt = webdriver.IeOptions() opt.profile = r'%s\Local\Microsoft\Windows\INetCache' % os.environ[ "USERPROFILE"] self.driver = webdriver.Ie(executable_path=ex, options=opt) # 添加隐式等待,凡是调find_element_xxx的地方,都会触发 self.driver.implicitly_wait(10) self.__write_excel(True, "浏览器打开成功") # self.driver.find_element_by_partial_link_text() # self.driver.get_screenshot_as_png() try: self.verify = Verify(config.config['vusername'], config.config['vpassword'], config.config['soft_id']) except Exception as e: logger.warn("您暂不支持验证码识别") return True except Exception as e: logger.exception(e) self.__write_excel(False, traceback.format_exc()) self.writer.save_close() # 退出,运行 exit(-1)