def clean(): try: clean_init() clean_window() except Exception as e: oper.log("清理失败" + str(e)) return True
def del_mq(resp): soa = SoaClient.get_soa('tqmq', 'operation') _, error = soa.remove('queue_case_ui_test', resp['msg_id']) if error: oper.log("删除队列发送异常:%s" % error, 2) pass if not _: oper.log("删除队列失败,返回信息为None", 2)
def clean_window(): try: check.wait_element("n,商城") oper.click("n,商城") check.wait_element("i,com.xingjiabi.shengsheng:id/ivClose") oper.click("i,com.xingjiabi.shengsheng:id/ivClose") check.wait_element("n,我") except Exception as e: oper.log("清理弹窗页面失败:" + str(e), 2)
def share_download(): """ 打开共享文件夹,从服务器下载apk文件 """ path = helper.read_config_item("apk", "path") try: oper.log("开始下载共享文件夹,读取文件...") get_file_dir_download(path) except Exception as e: oper.log("打开共享文件夹,从服务器下载文件失败:" + str(e), 2)
def get_mq(): soa = SoaClient.get_soa('tqmq', 'operation') # res, error = soa.pop(0) resp, error = soa.pop('queue_case_ui_test', 3600) if error: oper.log(u"获取队列失败,异常:" + error) if resp: if resp['msg_id']: oper.log(u"哇!队列终于来消息啦!开始吧。") return resp
def assert_not_exist_text(content): """ 判断文字是否不存在 Args: content: 文字,str Returns: 断言失败异常 """ if exist_text(content): oper.log(content + "该文字仍然存在", 2) raise TouchException(content + "该文字仍然存在")
def assert_not_exist_element(element_sequence): """ 判断文字是否存在 Args: element_sequence: 元素定位,str Returns: 断言失败异常 """ if exist_element(element_sequence): oper.log(element_sequence + "该对象仍然存在", 2) raise TouchException(element_sequence + "该对象仍然存在")
def assert_not_exist_toast(text): """ 判断浮窗是否不存在 Args: text: 元素定位,str Returns: 断言失败异常 """ if not no_exist_toast(text): oper.log(text + "该浮窗仍然存在", 2) raise TouchException(text + "该浮窗仍然存在")
def clean_init(): try: check.wait_element("i,com.xingjiabi.shengsheng:id/tvGuideLogin") check.exist_element("i,com.xingjiabi.shengsheng:id/tvGuideLogin") oper.driver_wait_click("i,com.xingjiabi.shengsheng:id/tvGuideLogin") oper.action_press(x=0.5, y=0.95) check.wait_element("n,请选择性别") check.exist_element("n,请选择性别") oper.click("i,com.xingjiabi.shengsheng:id/ivSwitchGenderMan") except Exception as e: oper.log("清理初始化页面失败:" + str(e), 2)
def run_case(self, result_message=None): """ 执行用例步骤 """ i = 1 for xml_key, xml_value in self.xml_detail["cases"].items(): oper.log("执行测试用例【" + str(xml_key) + "】第" + str(i) + "个测试用例", formats=self.log_message) self.run_before_case(xml_value) self.run_step(xml_key, xml_value, result_message) self.run_after_case(xml_value)
def keyboard_select(self): """ 判断第二层操作动作,物理键盘的操作 """ if self.oper_detail['oper_action'] in self.keyboard.keys(): key = self.oper_detail["oper_action"] value = self.keyboard.get(key) value() else: oper.log( "传入操作oper_action的值错误无法匹配,错误值为【" + str(self.oper_detail['oper_action']) + "】", 2)
def assert_select(self): """ 判断第二层操作动作,断言 """ if self.oper_detail['oper_action'] in self.asserts.keys(): key = self.oper_detail["oper_action"] value = self.asserts.get(key) self.assert_select_detail(key, value) else: oper.log( "传入操作oper_action的值错误无法匹配,错误值为【" + str(self.oper_detail['oper_action']) + "】", 2)
def get_pool(): soa_ui = SoaClient.get_soa('ui_auto', 'caseUIAccountPool') try: resp, error = soa_ui.getList() if error: oper.log("请求账号池失败,异常:" + error, 2) if not resp: return {} else: return resp except Exception as e: oper.log("请求账号池失败,异常:" + str(e), 2) return {}
def get_file_dir_download(share_path): """ 下载文件 :param share_path: 共享文件夹路径 """ try: file_list = os.listdir(share_path) for file in file_list: file_path = os.path.join(share_path, file) if os.path.isfile(file_path): # 如果是文件,就复制 copy_file_down(file_path) except Exception as e: oper.log("下载到本地失败:" + str(e), 2)
def read_http(file_path): """ 通过http读取xml文件 :param file_path: 读取的文件路径,必填项 :return: 读取后的xml文件 """ url = helper.read_config_item("http", "url") path = url + str(file_path).replace("\\", "") res = requests.get(path, stream=True) if res.status_code == 200: return res.raw else: oper.log("【%s】读取xml失败,失败原因:%s" % (file_path, res.text), 2) raise check.TouchException("【%s】读取xml失败" % file_path)
def run(self, result_message=None): """ 判断xml脚本的属性,属于前置后置或者普通用例 """ for key, value in self.xml_detail.items(): if "case-type" == key: if self.flag: types = "1" else: types = value if types == "1": # 加入判定登录时选择对应账号登录 if "Login/Login" in self.xml_file_path: try: login.login_read_xml(self.xml_file_path, self.port) self.write_result("端口:%s 登录成功!" % self.port) self.write_status("1") oper.log("端口:%s 登录成功!" % self.port) except Exception as e: self.write_result("端口:%s 登录失败!原因为:%s" % (self.port, str(e))) self.write_status("1") oper.log("端口:%s 登录失败!原因为:%s" % (self.port, str(e)), 2) else: self.run_case(result_message) elif types == "3": self.write_result("测试用例为后置用例无需执行") self.write_status("1") oper.log("测试用例为后置用例无需执行") else: self.write_result("测试用例为前置用例无需执行") self.write_status("1") oper.log("测试用例为前置用例无需执行")
def oper_select(self): """ 判断第二层操作动作,点击 输入之类 """ if self.oper_detail['oper_action'] in self.oper.keys(): key = self.oper_detail["oper_action"] value = self.oper.get(key) index = self.oper_select_detail(key, value) if 'get' in key: return index else: oper.log( "传入操作oper_action的值错误无法匹配,错误值为【" + str(self.oper_detail['oper_action']) + "】", 2)
def del_apk(apk_name): """ 判断本地是否存在apk,如果存在就删除 :param apk_name: apk名称 :return: """ dirs = str(apk_name).split("/")[0].split(":")[1] apk = str(apk_name).split("/")[1] local_path = helper.srcPath + '/common/' + dirs + '/' + apk if os.path.exists(local_path): try: os.remove(local_path) oper.log(str(local_path) + "本地apk,删除成功") except Exception as e: oper.log(str(local_path) + "本地apk,删除失败" + str(e), 2)
def copy_file_down(paths, local_path=None): """ # 复制文件或文件夹到本地 :param paths:拷贝路径 :param local_path:到本地路径 :return: """ if local_path: local_path = local_path else: local_path = helper.srcPath + '/common/' try: new_path = shutil.copy(paths, local_path) oper.log(str(new_path) + "复制成功!") except Exception as e: oper.log("复制到本地失败:" + str(e), 2)
def oper_select_detail(self, key, value): index = {} if 'send_keys' in key: location = self.dispose_location() value(location, self.dispose_cal(self.for_param()['text'])) elif 'wait_' in key: if 'text' in key: param = self.dispose_cal(self.for_param()['text']) else: param = self.dispose_location() self.wait_method(self.for_param(), value(param)) elif 'wait' == key: param = int(self.for_param()['time']) value(param) elif 'log' in key: param = self.dispose_cal(self.for_param()['text']) oper.log(param) elif 'get' in key: if 'text' in key: location = self.dispose_location() param = location sign = self.for_param()['sign'].replace("{", "").replace("}", "") index[sign] = value(param) elif 'page_resource' in key: index['page_resource'] = value() if index['page_resource']: self.write_result(index['page_resource']) else: self.write_result("获取页面资源失败!请排查") else: sign = self.for_param()['sign'].replace("{", "").replace("}", "") param = self.for_param()['values'] location = self.dispose_location() index[sign] = value(location, param) elif 'continuous' in key: location = self.dispose_location() param_number = int(self.for_param()['number']) param_time = int(self.for_param()['time']) value(location, param_number, param_time) elif 'switch_to' in key: value() else: location = self.dispose_location() value(location) return index
def xml_action(self, get_dict_data, save_value): """ 判断第一层操作 """ if self.oper_detail['oper'] in self.operate.keys(): self.save_param = get_dict_data key = self.oper_detail["oper"] value = self.operate.get(key) response = value() # 存储变量 if response: for key, value in response.items(): save_value(key, value) else: oper.log( "传入操作oper的值错误无法匹配,错误值为【" + str(self.oper_detail['oper']) + "】", 2)
def exist_apk(apk_name): """ 判断本地是否存在apk,如果不存在下载 :param apk_name: apk名称 :return: 更新apk """ dirs = str(apk_name).split("/")[0].split(":")[1] apk = str(apk_name).split("/")[1] local_path = helper.srcPath + '/common/' + dirs share_path = helper.read_config_item("apk", "path") if not os.path.exists(local_path): # 创建目录 os.makedirs(local_path) oper.log("创建apk目录:" + str(local_path)) file_list = os.listdir(local_path) if apk not in file_list: file_path = os.path.join(share_path, apk) copy_file_down(file_path, local_path)
def compare_not(predicted_value, actual_value): """ 比较 Args: predicted_value: 预期值 actual_value: 实际值 Returns: log信息 """ try: # 预计值predicted_value对比实际值actual_value assert str(predicted_value).replace(" ", "").replace("\n", "") != str(actual_value).replace(" ", "").replace( "\n", "") oper.log('校验成功。预计值:%s,实际值:%s' % (predicted_value, actual_value)) except AssertionError: oper.log('》》》》》校验失败。预计值:%s,实际值:%s' % (predicted_value, actual_value), 2) raise TouchException('》》》》》校验失败。预计值:%s,实际值:%s' % (predicted_value, actual_value))
def dispose_cal(self, values): expect_value = "" if ("{{" and "}}") in values: expect_sign = values.split("{{")[1].split("}}")[0] flag = 0 for key, value in self.save_param.items(): if expect_sign in key: flag = 1 # 获取到变量值 sign_value = self.save_param.get(expect_sign) expect_value = str(values).replace( expect_sign, sign_value).replace("{", "").replace("}", "") break if flag == 0: oper.log("找不到变量%s的值" % expect_sign, 2) raise check.TouchException("找不到变量%s的值" % expect_sign) else: expect_value = values return expect_value
def cal_select(self): """ 判断第二层操作动作,计算 """ if self.oper_detail['oper_action'] in self.cal.keys(): index = {} key = self.oper_detail["oper_action"] value = self.cal.get(key) value_1 = self.dispose_cal(self.for_param()['value_1']) value_2 = self.dispose_cal(self.for_param()['value_2']) if 'cal' not in key: sign = self.for_param()['cal_sign'].replace("{", "").replace( "}", "") index[sign] = value(value_1, value_2) return index else: value(value_1, value_2) else: oper.log( "传入操作oper_action的值错误无法匹配,错误值为【" + str(self.oper_detail['oper_action']) + "】", 2)
def dispose_equal(self): expect_value = "" actual_value = "" if ("{{" and "}}") in self.for_param()['expect_value']: expect_sign = str( self.for_param()['expect_value']).split("{{")[1].split("}}")[0] flag = 0 for key, value in self.save_param.items(): if expect_sign in key: flag = 1 # 获取到变量值 sign_value = self.save_param.get(expect_sign) expect_value = str(self.for_param()['expect_value']) \ .replace(expect_sign, sign_value) \ .replace("{", "").replace("}", "") break if flag == 0: oper.log("找不到预期变量%s的值" % expect_sign, 2) raise check.TouchException("找不到预期变量%s的值" % expect_sign) else: expect_value = self.for_param()['expect_value'] if ("{{" and "}}") in self.for_param()['actual_value']: actual_sign = self.for_param()['actual_value'].split( "{{")[1].split("}}")[0] flag = 0 for key, value in self.save_param.items(): if actual_sign in key: flag = 1 # 获取到变量值 sign_value = self.save_param.get(actual_sign) actual_value = str(self.for_param()['actual_value']) \ .replace(actual_sign, sign_value) \ .replace("{", "").replace("}", "") break if flag == 0: oper.log("找不到实际变量%s的值" % actual_sign, 2) raise check.TouchException("找不到实际变量%s的值" % actual_sign) else: actual_value = self.for_param()['actual_value'] return expect_value, actual_value
def compare_than(value_1, value_2, sign): """ 比较两个值大小 :param value_1: 值1 :param value_2: 值2 :param sign: 触发不同的比较,如1.大于,2.大于等于,3.小于,4.小于等于 :return: 比较结果 """ try: if sign == "大于": assert value_1 > value_2 elif sign == "大于等于": assert value_1 >= value_2 elif sign == "小于": assert value_1 < value_2 else: assert value_1 <= value_2 oper.log('校验成功。%s是%s %s' % (value_1, sign, value_2)) except AssertionError: oper.log('》》》》》校验失败。%s不是%s%s' % (value_1, sign, value_2), 2) raise TouchException('》》》》》校验失败。%s不是%s %s' % (value_1, sign, value_2))
def run_before_case(self, xml_value): """ 运行前置用例 Args: xml_value: 解析xml cases级别的value值 """ if "case-beforecases" in xml_value.keys(): j = 1 for before_key, before_value in xml_value[ "case-beforecases"].items(): if "beforecase-path" in before_value.keys(): oper.log("执行测试前置用例【" + str(before_value["beforecase-path"]) + "】", formats=self.log_message) try: run_init = RunXml(before_value["beforecase-path"], self.write_result, self.write_status, self.save_param, log_message=self.log_message, flag=1, port=self.port) run_init.run("执行测试前置用例【" + str(before_value["beforecase-path"]) + "】") except Exception as e: oper.log("执行测试前置用例【" + str(before_value["beforecase-path"]) + "】失败,原因是:" + str(e), 2, formats=self.log_message) self.write_result( "执行测试前置用例【" + str(before_value["beforecase-path"]) + "】失败,原因是:" + str(e)) self.write_status("0") pass j += 1 oper.log("执行前置用例【" + str(before_value["beforecase-path"]) + "】完成!", formats=self.log_message) del xml_value["case-beforecases"]
def run_after_case(self, xml_value): """ 运行后置用例 Args: xml_value: 解析xml cases级别的value值 """ if "case-aftercases" in xml_value.keys(): for after_key, after_value in xml_value["case-aftercases"].items(): if "aftercase-path" in after_value.keys(): oper.log("执行后置用例【" + str(after_value["aftercase-path"]) + "】", formats=self.log_message) try: run_init = RunXml(after_value["aftercase-path"], self.write_result, self.write_status, self.save_param, log_message=self.log_message, flag=1, port=self.port) run_init.run("执行后置用例【" + str(after_value["aftercase-path"]) + "】") except Exception as e: oper.log("执行后置用例【" + str(after_value["aftercase-path"]) + "】失败,原因是:" + str(e), 2, formats=self.log_message) self.write_result("执行后置用例【" + str(after_value["aftercase-path"]) + "】失败,原因是:" + str(e)) self.write_status("0") pass oper.log("执行测试用例【" + str(after_value["aftercase-path"]) + "】的后置用例执行完成!", formats=self.log_message) del xml_value["case-aftercases"]
def run_step(self, xml_key, xml_value, result_message=None): """ 运行脚本步骤 Args: xml_key: 解析xml cases级别的key值 xml_value: 解析xml cases级别的value值 result_message: 执行结果的前缀信息 """ case_key = "" if result_message: case_id = str(result_message) else: case_id = "执行测试用例【" + str(xml_key) + "】" try: for case_key, case_value in list(xml_value.items()): if "step" in case_key: oper.log(case_id + "的第" + str(case_key) + "个用例步骤", formats=self.log_message) action = XmlAction(case_value, self.write_result) action.xml_action(self.get_dict_data, self.save_value) oper.log('运行成功', formats=self.log_message) self.write_result("成功") self.write_status("1") except Exception as e: oper.log(case_id + "的第" + str(case_key) + "个用例步骤失败,原因是:" + str(e), 2, formats=self.log_message) if str(e): detail = str(e) else: detail = "" self.write_result( str(case_id + "的第" + str(case_key) + "个用例步骤失败,原因是:" + detail)) if result_message: self.write_status("1") else: self.write_status("0")