def wait_eleVisible(self, locator, times=30, poll_frequency=0.5, doc=''): ''' :param locator: 元素 :param times: :param poll_frequency: :param doc: :return: ''' MyLog().info("{0}等待元素{1}可见".format(doc, locator)) try: # 开始等待时间 start = datetime.datetime.now() WebDriverWait(self.driver, times, poll_frequency).until( EC.visibility_of_element_located(locator)) # 结束等待时间 end = datetime.datetime.now() # 求时间差 wait_time = (end - start).seconds MyLog().info('{0}查找{1}元素用了{2}'.format(doc, locator, wait_time)) except: MyLog().error("{0}等待元素{1}可见失败".format(doc, locator)) # 截图 self.save_screenshot(doc) raise
def get_element(self, locator, doc=''): MyLog().info("查找元素{0}可见".format(locator)) try: return self.driver.find_element(*locator) except: MyLog().error("{0}查找元素{1}可见失败".format(doc, locator)) # 截图 self.save_screenshot(doc) raise
def is_eleExist(self, locator, timeout=10, doc=''): MyLog().info("在{0}页面中是否存在元素{1}".format(doc, locator)) try: WebDriverWait(self.driver, timeout).until( EC.presence_of_element_located(locator)) MyLog().info("{0}秒内页面{1}存在元素{2}".format(timeout, doc, locator)) return True except: MyLog().info("{0}秒内页面{1}不存在元素{2}".format(timeout, doc, locator)) return False
def click_element(self, locator, doc=''): # 找元素 ele = self.get_element(locator, doc) # 元素操作 MyLog().info("{0}点击元素:{1}".format(doc, locator)) try: ele.click() except: MyLog().info("元素点击操作失败") self.save_screenshot(doc) raise
def time_sleep(seconds): log = MyLog().my_log() log.info('进入时间等待方法') if seconds.isdigit() or isinstance(seconds, int): time.sleep(int(seconds)) log.info('等待时间%s秒' % seconds) else: log.info('参数seconds输入错误')
def test_login_00_wrong_format(self, access_web, data): access_web[1].login(data['user'], data['password']) time.sleep(1) MyLog().info('获取的提示信息为{0}'.format( access_web[1].get_message_no_exist_and_wrong_user_password())) assert access_web[1].get_message_no_exist_and_wrong_user_password( ) == data['check']
def get_text(self, locator, doc=''): # 找元素 ele = self.get_element(locator, doc) try: return ele.text except: MyLog().info('获取元素内容失败!!!') self.save_screenshot(doc) raise
def get_element_attribute(self, locator, attr, doc=''): # 找元素 ele = self.get_element(locator, doc) try: return ele.get_attribute(attr) except: MyLog().info("获取元素的属性失败!!!") self.save_screenshot(doc) raise
def input_text(self, locator, text, doc=''): # 找元素 ele = self.get_element(locator, doc) # 输入操作 try: ele.send_keys(text) except: MyLog().info('元素输入操作失败!!!') self.save_screenshot(doc) raise
def save_screenshot(self, name): # 图片名称,模块名-页面名称_某个操作名称_时间.png # 当前时间 screen_shot_time = time.strftime('%Y-%m-%d-%H_%M_%S', time.localtime(time.time())) file_path = project_path.screen_shot_path + '\\' + name + '_' + screen_shot_time + '.png' try: self.driver.save_screenshot(file_path) except: MyLog().info('{0}截图失败'.format(name)) raise
def access_web(): global driver # 前置操作 MyLog().info('-----所用用例之前的,setup---整个测试类只执行一次') driver = webdriver.Chrome() driver.maximize_window() driver.get(CD.login_url) lg = Login_Page(driver) yield (driver, lg) # 分割线,后面接返回值,fixture的函数名称用来接收他的返回值 # 后置操作 print('---使用用例之后的,teardown--整个测试类只执行一次') driver.quit()
SQL后置处理,有更改、删除和新增操作,暂时不支持查询和参数提取操作 :param sql_param: 单元格里的参数 :return: 暂无返回 ''' self.logger.info('——进入SQL后置处理——') if isinstance(sql_param, dict): sql_param = [sql_param] for sub_sql in sql_param: sql = sub_sql['sql'] db = sub_sql.get('db') if sub_sql.get('db') else 1 DoMysql(self.logger).commit_mysql(sql, db=db) self.logger.info('——SQL后置处理完成——') if __name__ == '__main__': logger1 = MyLog().my_log() ss = { 'request_type': None, 'case_id': 1, 'correlation': None, 'json': None, 'method': 'post', 'expect_result': "{'age': '${__age(hello,world)}','pen':'ios_increase_0001','apple':'increase_5','ran':'randstr_3'}", 'param': "{'teamId': '${teamId+1}', 'companyId': '${companyId+1}', 'Base64Photo': {'base64':'120KB.jpg'},"
# !/usr/bin/evn python # -*- coding:utf-8 -*- from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.alert import Alert from common.projectPath import picture_path from common.my_log import MyLog import time logging = MyLog() class BasePage: def __init__(self, driver): self.driver = driver # 等待元素可见 def wait_eleVisible(self, locator, module_name=None, timeout=30, poll_frequency=0.5): ''' :param locator: 元素定位表达式,元组类型。如:(By.xpath,'//div[@class="button"]') :param timeout: 等待时长 :param poll_frequency: 轮询频率 :param module_name: 等待失败时截图操作,图片文件所需要的模块名称 :return: None '''
class BasePage: log = MyLog() def __init__(self, driver): self.driver = driver # 元素可见 def wait_ele_view(self, locator, times=20, poll_frequency=0.5, doc=''): self.log.info("元素{}在{}界面可见".format(locator, doc)) try: WebDriverWait(self.driver, times, poll_frequency).until( EC.visibility_of_element_located(locator)) except: self.save_screenshot(doc) raise def wait_ele_exist(self, locator, times=30, poll_frequency=0.2, doc=''): try: WebDriverWait(self.driver, times, poll_frequency).until( EC.presence_of_element_located(locator)) return True except: self.save_screenshot(doc) return False # 获取元素 def get_element(self, locator, doc=''): try: return self.driver.find_element(*locator) except: self.save_screenshot(doc) raise # 输入操作 def input_text(self, locator, text, doc=''): ele = self.get_element(locator) try: ele.send_keys(text) except: self.save_screenshot(doc) raise # 点击操作 def ele_click(self, locator, doc=''): ele = self.get_element(locator) try: ele.click() except: self.save_screenshot(doc) raise # 获取元素文本 def get_ele_text(self, locator, doc=''): ele = self.get_element(locator) try: return ele.text except: self.save_screenshot(doc) raise # 获取元素属性 def get_ele_attribute(self, locator, doc=''): ele = self.get_element(locator) try: return ele.get_attribute() except: self.save_screenshot(doc) raise # alert操作 def alert_txt(self): time.sleep(0.5) alert = self.driver.switch_to.alert return alert.text def alert_acept(self): time.sleep(0.5) alert = self.driver.switch_to.alert alert.accept() # 截图 def save_screenshot(self, doc=''): file_path = dl.scree_dir + '/{}.png'.format(doc) try: self.driver.save_screenshot(file_path) except: logging.exception("截图失败") raise
class TestLogin(unittest.TestCase): def setUp(self): self.logger = MyLog() self.logger.info('开始测试') print('开始测试') @data(*test_data) def test_login(self, data_item): global TOKEN print('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) self.logger.info('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) params = eval(data_item['param']) if data_item['module'] == '登录': if params['mobilecaptcha'] == 'code': #去数据库查询验证码替换 for i in [2]: sql = 'SELECT idstring FROM `pre_captcha_mobile` WHERE mobile={0} ORDER BY captchaid DESC LIMIT 1'.format( params['phone']) code = DoMysql().do_mysql(sql) params['mobilecaptcha'] = code[0][0] else: params['access_token'] = TOKEN print('测试数据为{0}'.format(params)) self.logger.info('测试数据为{0}'.format(params)) res = HttpRequtser().http_request(data_item['url'], params, data_item['HttpMethod'], verify=False, headers=header) print('测试结果是{0}'.format(res.json())) self.logger.info('测试结果是{0}'.format(res.json())) if data_item['module'] == '登录': if res.json( )['data']['access_token']: # 任何非空数据的布尔值都为True cookies是一个类字典的格式 TOKEN = res.json()['data'][ 'access_token'] # 如果cookies不为空 就替换全局变量的COOKIES 修改全局变量 try: self.assertEqual(str(data_item['ExpectedResult']), str(res.json()['error_code'])) self.assertEqual(res.status_code, 200) print('用例通过') self.logger.info('用例通过') TestResult = 'PASS' Comment = None except AssertionError as e: print('用例失败错误是{}'.format(e)) self.logger.error('用例失败错误是{}'.format(e)) TestResult = 'Failed' Comment = res.json()['error_message'] raise e finally: DoExce(project_path.test_case_path).write_back( 'login', data_item['id'] + 1, res.json()['error_code'], TestResult, Comment) def tearDown(self): print('用例结束') self.logger.info('用例结束')
import requests from common.my_log import MyLog from ddt import ddt, data import unittest from common.do_excel import DoExcel from common.project_path import case_path from test_case.http_request import HttpRequest test_data = DoExcel(case_path, 'register').read_data() my_log = MyLog() def jianquan(): url = 'http://www.testingedu.com.cn/inter/HTTP/auth' resp = requests.post(url) return eval(resp.text)['token'] @ddt class TestRegister(unittest.TestCase): """测试testing网站注册""" @data(*test_data) def test_register(self, case): # 执行测试 # global TestResult # global token # 声明全局变量 method = case['Method'] url = case['Url'] param = eval(case['Params']) h = {'token': jianquan()} # 3.发起测试
class TestAccount(unittest.TestCase): def setUp(self): self.logger=MyLog() self.logger.info('开始测试') def tearDown(self): print('用例结束') self.logger.info('用例结束') @data(*test_data) def test_account(self,data_item): print('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) self.logger.info('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) params = eval(data_item['param']) params['access_token']=GetInfoData().get_token() print('测试数据为{0}'.format(params)) self.logger.info('测试数据为{0}'.format(params)) res = HttpRequtser().http_request(data_item['url'], params, data_item['HttpMethod'], verify=False, headers=GetInfoData().get_hander()) print('测试结果是{0}'.format(res.json())) self.logger.info('测试结果是{0}'.format(res.json())) try: self.assertEqual(str(data_item['ExpectedResult']),str(res.json()['error_code'])) self.assertEqual(res.status_code,200) print('用例通过') self.logger.info('用例通过') TestResult='PASS' Comment=None except AssertionError as e: print('用例失败错误是{}'.format(e)) self.logger.error('用例失败错误是{}'.format(e)) TestResult = 'Failed' Comment=res.json()['error_message'] raise e finally: DoExce(project_path.test_case_path).write_back('login',data_item['id']+1,res.json()['error_code'],TestResult,Comment)
class TestCommunity(unittest.TestCase): '''社区''' def setUp(self): self.logger=MyLog() self.logger.info('开始测试') @data(*test_data) def test_community(self, data_item): self.logger.info('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) #查找tid,cid,rid并替换 data_item=replace_data(data_item) # if data_item['param'].find('${tid}')!=-1: # data_item['param']=data_item['param'].replace('${tid}', str(getattr(GetInfoData,'RID'))) params = eval(data_item['param']) #添加token params['access_token'] = GetInfoData().get_token() self.logger.info('测试数据为{0}'.format(params)) #发送请求 res = HttpRequtser().http_request(data_item['url'],params , data_item['HttpMethod'], verify=False, headers=GetInfoData().get_hander()) self.logger.info('测试结果是{0}'.format(res.json())) try: #断言 self.assertEqual(str(data_item['ExpectedResult']),str(res.json()['error_code'])) self.assertEqual(res.status_code,200) self.logger.info('用例通过') TestResult='PASS' Comment=None if data_item['description'] == '发布动态': tid = res.json()['data']['tid'] # 替换info里的tid global RID,TID,CID setattr(GetInfoData,'TID',tid) except AssertionError as e: self.logger.error('用例失败错误是{}'.format(e)) TestResult = 'Failed' Comment=res.json()['error_message'] raise e finally: DoExce(project_path.test_case_path).write_back('community',data_item['id']+1,res.json()['error_code'],TestResult,Comment) def tearDown(self): self.logger.info('用例结束')
class TestApi(unittest.TestCase): '''文章,背景音的接口''' def setUp(self): self.logger = MyLog() self.logger.info('开始测试') print('开始测试') @data(*test_data) def test_api(self, data_item): # data_item=Application_profiles(data_item) print('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) self.logger.info('正在进行第{0}条用例:{1}'.format(data_item['id'], data_item['description'])) print('测试数据为{0}'.format(data_item['param'])) self.logger.info('测试数据为{0}'.format(data_item['param'])) res = HttpRequtser().http_request(data_item['url'], eval(data_item['param']), data_item['HttpMethod'], verify=False, headers=GetInfoData().get_hander()) print('测试结果是{0}'.format(res.json())) self.logger.info('测试结果是{0}'.format(res.json())) # if res.cookies: # 任何非空数据的布尔值都为True cookies是一个类字典的格式 # COOKIES = res.cookies # 如果cookies不为空 就替换全局变量的COOKIES 修改全局变量 try: self.assertEqual(str(data_item['ExpectedResult']), str(res.json()['error_code'])) self.assertEqual(res.status_code, 200) print('用例通过') self.logger.info('用例通过') TestResult = 'PASS' Comment = None except AssertionError as e: print('用例失败错误是{}'.format(e)) self.logger.error('用例失败错误是{}'.format(e)) TestResult = 'Failed' Comment = res.json()['error_message'] raise e finally: DoExce(project_path.test_case_path).write_back( 'mindfulness', data_item['id'] + 1, res.json()['error_code'], TestResult, Comment) def tearDown(self): print('用例结束') self.logger.info('用例结束')
def setUp(self): self.logger=MyLog() self.logger.info('开始测试')
class Page: def __init__(self, driver: Chrome): self.driver = driver self.driver.maximize_window() self.logging = MyLog() # 导入日志类 def find_element_wait(self, locator, timeout=20, poll_frequency=0.5) -> WebElement: # 页面元素查找等待 try: wait = WebDriverWait(self.driver, timeout, poll_frequency) element = wait.until(ec.presence_of_element_located(locator)) except Exception as e: # 写入日志 self.logging.error('元素定位失败{}'.format(e)) self.get_screen_shot('等待元素不可见') raise e return element def click_element_wait(self, locator, timeout=20, poll_frequency=0.5) -> WebElement: try: # 等待页面元素可以点击 wait = WebDriverWait(self.driver, timeout, poll_frequency) element = wait.until(ec.element_to_be_clickable(locator)) except Exception as e: self.logging.error('元素定位失败{}'.format(e)) self.get_screen_shot('等待元素不可点击') raise e return element def current_handles(self): # 获得当前窗口数 try: handles = self.driver.window_handles except Exception as e: self.logging.error('获取窗口数失败{}'.format(e)) raise e return handles def switch_windows_wait(self, handles, timeout=20, poll_frequency=0.5): # 切换新窗口 try: wait = WebDriverWait(self.driver, timeout, poll_frequency) wait.until(ec.new_window_is_opened(handles)) self.driver.switch_to.window( self.driver.window_handles[-1]) # 切换窗口 except Exception as e: self.logging.error('切换窗口失败{}'.format(e)) raise e def switch_frame_wait(self, locator, timeout=20, poll_frequency=0.5) -> WebElement: # 切换到frame try: wait = WebDriverWait(self.driver, timeout, poll_frequency) element = wait.until( ec.frame_to_be_available_and_switch_to_it(locator)) self.driver.switch_to.default_content() except Exception as e: self.logging.error('frame切换失败{}'.format(e)) raise e return element def switch_main_page(self): # 切换回主文档,跳出所有frame try: self.driver.switch_to.default_content() except Exception as e: self.logging.error('回到主界面失败{}'.format(e)) raise e def get_screen_shot(self, name): """截图""" mkdir(img_path) self.driver.save_screenshot(img_path + '//' + name + '.png') @staticmethod def send_file(file): # 上传文件 time.sleep(2) dialog = win32gui.FindWindow("#32770", "打开") # 一级窗口 # 找到窗口 ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) # 二级 comboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, "ComboBox", None) # 三级 edit = win32gui.FindWindowEx(comboBox, 0, 'Edit', None) # 四级 button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 四级 # 操作 time.sleep(2) win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, file) # 发送文件路径 time.sleep(2) win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 点击打开按钮
import requests, json from common.my_log import MyLog logger = MyLog('登录模块') class Httprequest: #初始化url和param,url:访问地址 param:请求参数 def __init__(self, url, param): self.url = url self.param = param def http_request(self, method, headers=None, cookies=None): if method.upper() == 'GET': try: res = requests.get(self.url, self.param, headers=headers, cookies=cookies) except Exception as e: logger.error("执行get请求报错,错误是:{0}".format(e)) elif method.upper() == 'POST': try: res = requests.post(self.url, self.param, headers=headers, cookies=cookies) except Exception as e: logger.error("执行post请求报错,错误是:{0}".format(e)) else: print("你的请求方式不对!")
def __init__(self, driver: Chrome): self.driver = driver self.driver.maximize_window() self.logging = MyLog() # 导入日志类
# -*- coding: utf-8 -*- # @Time : 2018/7/5 20:51 # @Author : Emerson # @Email : [email protected] # @File : do_mysql.py import mysql.connector from conf import project_path from common.my_log import MyLog from common.read_config import ReadConfig logger = MyLog() class DoMysql: def do_mysql(self, sql, data): config = eval(ReadConfig().read_config(project_path.db_conf_path, 'DATABASE', 'config')) cnn = mysql.connector.connect(**config) cursor = cnn.cursor() try: cursor.execute(sql, data) result = cursor.fetchone() return result except Exception as e: logger.error('查询数据出错了,报错是:%s' % e) finally: cursor.close() cnn.close() if __name__ == '__main__':
from common import project_path from common.post_processor import PostProcessor from common.config_element import ConfigElement # 获取用例的执行模式 mode = ReadConfig().read_config(project_path.case_conf_path, 'CASE', 'mode') case_list = eval(ReadConfig().read_config(project_path.case_conf_path, 'CASE', 'case_list')) # 获取测试数据、ip地址 sheet = 'add_workers' test_data = DoExcel(project_path.test_data_path, sheet).read_data(mode, case_list) IP = ReadConfig().read_config(project_path.http_conf_path, 'HTTP', 'test_ip') logger = MyLog().my_log() post_processor = PostProcessor(logger) @ddt class TestHttpRequest(unittest.TestCase): def setUp(self): self.excel = DoExcel(project_path.test_data_path, sheet) with open(project_path.yaml_path, encoding='utf-8') as file: self.yaml_data = yaml.load(file, Loader=yaml.UnsafeLoader) logger.info("开始测试啦") @data(*test_data) def test_http_request(self, sub_data): logger.info("目前正在执行第%s条用例" % sub_data['case_id'])