测试工具类
1、base
class Base:
def __init__(self, driver=None):
if driver is None:
log.info("正在初始化driver对象:{}".format(driver))
self.driver = DriverUtils.get_admin_driver()
else:
self.driver = driver
# 定位元素
def base_find(self, loc, timeout=10, poll=0.5):
log.info("正在查找元素:{}".format(loc))
return WebDriverWait(self.driver, timeout, poll).until(EC.presence_of_element_located(loc))
# 点击方法
def base_click(self, loc):
log.info("正在调用点击元素方法:{}".format(loc))
# 获取元素
self.base_find(loc).click()
# 输入方法
def base_input(self, loc, value):
log.info("正在调用输入元素方法:{} 输入内容:{}".format(loc, value))
# 获取元素
el = self.base_find(loc)
# 清空元素
el.clear()
# 输入
el.send_keys(value)
# 获取文本
def base_text(self, loc):
log.info("正在调用获取文本方法:{}".format(loc))
return self.base_find(loc).text
# 截图
def base_screenshot(self):
log.info("正在调用截图方法")
# os.sep: \
# img_path = DIR_PATH + os.sep + "img" + os.sep + "{}.png".format(time.strftime("%Y:%m:%d-%H:%M:%S"))
self.driver.get_screenshot_as_file(DIR_PATH + "/img/{}.png".format(time.strftime("%Y:%m:%d-%H:%M:%S")))
# 切换frame
def base_switch_frame(self, loc):
log.info("正在调用切换frame方法,切换对象:{}".format(loc))
# 获取元素
el = self.base_find(loc)
# 切换
self.driver.switch_to.frame(el)
# 返回默认frame
def base_default_frame(self):
self.driver.switch_to.default_content()
# 切换窗口
def window(self, window_name):
return self.driver.switch_to.window(window_name)
2、app_start_base
class Start(object):
def __init__(self):
# 定义字典变量
self.desired_caps = {}
# 字典追加启动参数 设备信息
self.desired_caps["platformName"] = "Android"
self.desired_caps["platformVersion"] = "5.1.1"
self.desired_caps["deviceName"] = "127.0.0.1:62001"
# app信息
self.desired_caps["appPackage"] = "com.android.settings"
self.desired_caps["appActivity"] = ".Settings"
# 设置中文
self.desired_caps["nicodeKeyboard"] = True
self.desired_caps["resetKeyboard"] = True
# 重置:全新首次使用app;不重置:记录用户之前行为
self.desired_caps['noReset'] = False
# toast uiautomator2
self.desired_caps['automationName'] = 'uiautomator2'
# 获取driver
self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", self.desired_caps)
self.driver.implicitly_wait(10)
3、common_assert
"""
定义 通用的 工具函数,实现断言
"""
def common_assert(resp, status_code, success, code, message):
assert status_code == resp.status_code
assert success is resp.json().get("success")
assert code == resp.json().get("code")
assert message in resp.json().get("message")
4、config
# 定义全局变量,获取项目路径
BASE_DIR = os.path.dirname(__file__)
# 定义 数据库工具类
class DBTools(object):
# 创建连接 - 类方法。可以直接使用类名调用!
@classmethod
def __create_conn(cls):
conn = pymysql.connect(host="211.103.136.244", port=7061, user="student", password="iHRM_student_2021",
database="ihrm", charset="utf8")
# 不能遗漏
return conn
# 查一条记录 - 封装为类方法,方便调用
@classmethod
def query_one(cls, sql):
my_conn = None
my_cursor = None
res = None
try:
# 创建连接, 借助类名,调用 类方法 create_conn
my_conn = DBTools.__create_conn()
# 创建游标
my_cursor = my_conn.cursor()
# 执行 sql 语句,做查询
my_cursor.execute(sql)
# 提取一条记录
res = my_cursor.fetchone()
except Exception as err:
print("执行查询SQL失败:", str(err))
finally:
# 关闭游标
my_cursor.close()
# 关闭连接
my_conn.close()
# 返回查询结果
return res
# 增删改记录
@classmethod
def db_uid(cls, sql):
my_conn = None
my_cursor = None
try:
# 创建连接
my_conn = DBTools.__create_conn()
# 创建游标
my_cursor = my_conn.cursor()
# 执行 增删改 语句
my_cursor.execute(sql)
print("Affected rows:", my_conn.affected_rows())
# 提交事务
my_conn.commit()
except Exception as err:
print("执行 增删改 SQL 失败:", str(err))
# 回滚事务
my_conn.rollback()
finally:
# 关闭游标
my_cursor.close()
# 关闭连接
my_conn.close()
if __name__ == '__main__':
# result = DBTools.query_one("select * from t_hero;")
# print("查询语句的结果:", result)
# DBTools.db_uid("update t_book set `read` = 100 where id = 3;")
6、日志
def init_log_config(filename, when='midnight', interval=1, backup_count=7):
"""
功能:初始化日志配置函数
:param filename: 日志文件名
:param when: 设定日志切分的间隔时间单位
:param interval: 间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
:param backup_count: 保留日志文件的个数
:return:
"""
# 1. 创建日志器对象
logger = logging.getLogger()
# 2. 设置日志打印级别
logger.setLevel(logging.DEBUG)
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别
# 3. 创建处理器对象
# 控制台对象
st = logging.StreamHandler()
# 日志文件对象
fh = logging.handlers.TimedRotatingFileHandler(filename,
when=when,
interval=interval,
backupCount=backup_count,
encoding='utf-8')
# 4. 日志信息格式
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
formatter = logging.Formatter(fmt)
# 5. 给处理器设置日志信息格式
st.setFormatter(formatter)
fh.setFormatter(formatter)
# 6. 给日志器添加处理器
logger.addHandler(st)
logger.addHandler(fh)
if __name__ == '__main__':
# 初始化日志
init_log_config(BASE_DIR + '/log/sh27.log', interval=3, backup_count=5)
# 打印输出日志信息
logging.debug('我是一个调试级别的日志')
logging.info("AAA BBB CCC")
logging.error("xxxx 错误。。")
7、read_json
# 定义工具函数,读取json文件中的数据,转换成 [(),(),()] 格式数据
def read_json_data(filename):
with open(filename, "r", encoding="utf8") as f:
json_data = json.load(f)
login_list = []
for data in json_data:
tmp = tuple(data.values())
login_list.append(tmp)
return login_list
if __name__ == '__main__':
# res = read_json_data("../data/login_data.json")
filename = BASE_DIR + "/data/login_data.json"
res = read_json_data(filename)
print(res)
8、write_json
def write_json(value):
file_path = DIR_PATH + "/data/" + "expect.json"
with open(file_path, "w", encoding="utf-8") as f:
data = {"expect": [{"desc": "app订单编号", "order_no": value}]}
json.dump(data, f)
9、get_el_text
# 函数: 公用的获取任意元素文本
def get_el_text(driver, xpath_str):
# 获取元素文本
try:
msg = WebDriverWait(driver, 10, 1). \
until(lambda x: x.find_element(By.XPATH, xpath_str).text)
print(msg)
except Exception as e:
logging.error(f"没有获取到{xpath_str}的元素对象文本!")
msg = None
# 返回获取的文本
return msg
10、el_is_exist_by_text
# 函数: 根据文本判断当前页面是否有对应的元素对象
def el_is_exist_by_text(driver, is_app, key_text):
"""
:param driver: 浏览器对象
:param is_app: 判断是否是app
:param key_text: 要判断的文本
:return:
"""
# 判断是否是app
if is_app:
xpath_str = f"//*[@text='{key_text}']"
else:
xpath_str = f"//*[text()='{key_text}']"
# 根据本次新增的联系人信息的文本, 到界面上找元素,如能找到则代表新增成功找不到则失败截图
try:
# 如找到元素对象则把元素对象赋值给is_suc
is_suc = WebDriverWait(driver, 10, 1). \
until(lambda x: x.find_element(By.XPATH, xpath_str))
except Exception as e:
# 找不到则给is_suc赋值为False
is_suc = False
# 截图
driver.get_screenshot_as_file(f"{key_text}未找到.png")
logging.error(f"未找到文本为{key_text}的元素对象!")
# 返回是否找到结果
return is_suc