1、本框架使用Python开发语言,结合selenium,unnitest单元测试框架,再采用PO模型进行封装,整个框架结构一共包含了十大模块,如下图所示:
1、base层:基础层,存放我们的基础定位元素的方法,一共八种常用的方法;
2、business层:业务层,存放我们业务功能处理;
3、case层:存放我们测试用例;
4、congfig层:存放元素的定位信息;
5、handle层:存放页面的操作信息;
6、img层:存放图片信息;
7、log层:存放日志信息;
8、page层:存放页面信息;
9、report层:存放测试报告信息;
10、until层:存放工具类信息;
1、本框架配置文件采用的是ini文件存储,所以第一步是在until层,创建读取ini文件:
# 定义全局属性
def __init__(self, file_name=None, node=None):
# 定义默认文件读取
if file_name is None:
file_name = r'C:UsersMrlinPycharmProjectsCost_management_systemconfigYuanGon.ini'
# 定义默认ini文件头读取
if node is None:
self.node = 'RegisterElement'
else:
self.node = node
self.cf = self.getIni(file_name)
# 读取ini文件
def getIni(self, file_name):
cf = configparser.ConfigParser()
cf.read(file_name, encoding='UTF-8')
return cf
# 获取ini文件的数据值
def getMessage(self, node, key):
data = self.cf.get(node, key)
return data
2、写好读取ini配置文件之后,开始进行第二步,在base层定义我们selenium操作页面元素的方法:
def __init__(self, driver):
self.driver = driver
def get_element(self, file_path, note, key):
# 读取ini文件相关元素配置信息
read_ini = Read_ini(file_path)
data = read_ini.getMessage(note, key)
# 规定配置文件定位信息写法,>左边为定位方法、右边为定位信息
by = data.split('>')[0]
value = data.split('>')[1]
# 八大定位方式
try:
if by == 'id':
return self.driver.find_element_by_id(value)
elif by == 'name':
return self.driver.find_element_by_name(value)
elif by == 'className':
return self.driver.find_element_by_class_name(value)
elif by == 'xpath':
return self.driver.find_element_by_xpath(value)
elif by == 'link_text':
return self.driver.find_element_link_text(value)
elif by == 'partial_link_text':
return self.driver.find_element_partial_link_text(value)
elif by == 'css_selector':
return self.driver.find_element_css_selector(value)
else:
return self.driver.find_element_tag_name(value)
except:
return None
3、两份文件编写完成后,就可以在开始第三步,再config层编写我们的定位元素配置信息了:
;登录页面相关定位信息 ;[]内内容为node,=号左边为key,右边内容根据‘>’拆分 [LoginElement] ;选择账号登录 salecard_select = xpath>//span[text()='账号登录'] ;用户名 salecard_login_Name = xpath>//input[@placeholder='账号'] ;密码 salecard_login_Password = xpath>//input[@placeholder='密码'] ;验证码 salecard_code = xpath>//input[@placeholder='请输入验证码'] ;验证码图片 salecard_code_img = xpath>//img[@alt='验证码'] ;登录按钮 salecard_login_Button = xpath>//span[text()='登录'] [URL] ;系统网址 login_url = http://test-passport.gzjunbo.net/login/index.html?callback=http://test-card-admin.liulianglf.cn/index.html
4、配置信息编写完成之后,便可以开始第四步,在page层编写业务所需的页面信息:
def __init__(self, driver):
# base层读取ini文件实例化
self.login_find_element = MatchElementPosition(driver)
# 登录元素信息配置文件存放路径
self.file_path = os.path.abspath(os.path.dirname(os.getcwd())) + r'config' + r'salecard_login.ini'
# 获取登录方式选择框定位信息
def get_login_select(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_select')
# 获取用户名输入框定位信息
def get_login_name(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Name')
# 获取密码输入框定位信息
def get_login_password(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Password')
# 获取验证码定位信息
def get_login_code(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_code')
# 获取验证码图片定位信息
def get_login_code_img(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_code_img')
# 获取登录按钮定位信息
def get_login_button(self):
return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Button')
5、编写完成页面信息之后,便可以开始第五步,再handle层编写页面操作信息了:
def __init__(self, driver):
# page层实例化
self.salecard_login_page = SalecradLoginPage(driver)
# 选择登录方式
def click_select(self):
return self.salecard_login_page.get_login_select().click()
# 输入用户名
def send_name(self, username):
return self.salecard_login_page.get_login_name().send_keys(username)
# 输入密码
def send_password(self, password):
return self.salecard_login_page.get_login_password().send_keys(password)
# 输入验证码
def send_code(self, code):
return self.salecard_login_page.get_login_code().send_keys(code)
# 点击登录按钮
def click_button(self):
return self.salecard_login_page.get_login_button().click()
6、编写完成页面操作的脚本之后,可以开始开始第六步,在business层编写业务处理逻辑:
def __init__(self, driver):
self.driver = driver
self.login_handle = LoginHandle(driver)
self.getcode = GetCode(driver)
# 登录公共类
def user_operate(self, name, password):
# 选择登录方式
self.login_handle.click_select()
time.sleep(1)
# 输入用户名
self.login_handle.send_name(name)
time.sleep(1)
# 输入密码
self.login_handle.send_password(password)
time.sleep(1)
# 获取验证码
self.getcode.get_img(r'E:Knowledgeimgwhole_code.png', r'E:Knowledgeimgcode.png')
code = self.getcode.get_code(r'E:Knowledgeimgcode.png')
# 输入验证码
self.login_handle.send_code(code)
time.sleep(1)
def success_assert(self):
# 获取页面标题,用于断言
text = self.driver.title
# 成功断言
if text == '酬金业务-运营管理后台':
return True
elif text == '登录中心':
return True
else:
return False
# 登录业务操作
def user_normal_operate(self, name, password):
# 输入用户信息
self.user_operate(name, password)
time.sleep(1)
# 点击登录按钮
self.login_handle.click_button()
time.sleep(5)
# 判断是否登录成功
return self.success_assert()
7、到这已经完成所有的基本操作,接下来便是在case层编写我们的测试用例,因为我们在case层使用了log日志记录、读取excel进行参数化、以及使用HTMLtestrunner进行报告输出,所以呢需要在until层把这些工具类先编写好,方便调用;
<1>创建日志文件,读取log日志:
def __init__(self):
self.logger = logging.getLogger()
self.logger.setLevel(logging.INFO)
# 文件名字
base_dir = os.path.abspath(os.path.join(os.path.dirname("__file__"), os.path.pardir)) # 获取根目录
log_file = datetime.datetime.now().strftime('%Y-%m-%d') + '-' + 'log.ini' # 获取带时间文件名
log_name = base_dir + "/log/" + log_file # 拼接日志存放路径
# 文件输出日志
self.file_handle = logging.FileHandler(log_name, 'a', encoding='utf-8')
formatter = logging.Formatter('%(asctime)s %(filename)s ---> %(funcName)s %(levelno)s: %(levelname)s ---> %(message)s')
self.file_handle.setFormatter(formatter)
self.logger.addHandler(self.file_handle)
def get_log(self):
return self.logger
def close_log(self):
self.logger.removeHandler(self.file_handle)
self.file_handle.close()
<2>创建excel文件,读取excel文件:
def __init__(self, excel_path=None, index=None):
# Excel表存放路径;
if excel_path is None:
excel_path = r'E:KnowledgeconfigTest_case_parameters.xls'
else:
self.excel_path = excel_path
# 数据表位置确定;
if index is None:
index = 0
else:
self.index = index
# 打开Excel表格;
self.data = xlrd.open_workbook(excel_path)
self.table = self.data.sheets()[index] # 确定数据表位置;
# 获取表格数据行数
def get_row(self):
rows = self.table.nrows # 获取表格的行;
if rows >= 1:
return rows
return None
# 获取某个单元格内容
def get_cell(self, row, column):
rows = self.get_row()
if rows >= row:
title = self.table.cell(row, column).value
return title
return None
# 获取excel表某列数据
def get_column_data(self, column):
result = []
rows = self.get_row()
if rows is not None:
for i in range(1, rows):
value = self.table.cell(i, column).value
result.append((value))
return result
return None
# 获取excel表格全部数据
def get_excel_data(self):
result = []
rows = self.get_row()
if rows is not None:
for i in range(1, rows):
value = self.table.row_values(i)
result.append((value))
return result
return None
# 写入数据
def write_data(self, row, column, value):
# 复制旧数据
excel_value = self.data
write_data = copy(excel_value)
# 写入新数据
if row >= 1 and column >= 0:
write_data.get_sheet(0).write(row, column, value)
write_data.save(r'E:KnowledgeconfigTest_case_parameters.xls')
return None
<3>做完这两步,接下来可以直接在case层编写我们的测试用例文件:
@ddt.ddt
class Knowledge(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.log = RecordLog()
cls.logger = cls.log.get_log()
def setUp(self):
# 打开网页
self.RP = Premise()
self.RP.get_url()
# 正常登录测试
# unnitest框架采用ddt进行参数化操作
@ddt.data(*data)
def test_normal_login(self, data):
# 输入数据
name, password = data
# 向business层输入数据
case = self.RP.LB.user_normal_operate(name, password)
# 根据business层断言返回的结果判断用例是否执行成功
self.assertTrue(case)
# 输出日志信息
self.logger.info('test is chrome')
def tearDown(self):
# 关闭网页
self.RP.driver.quit()
@classmethod
def tearDownClass(cls):
cls.log.close_log()
8、最后一步便是,执行我们的case,报告采用HTMLtestrunner:
# 待执行用例的目录
def allcase():
case_dir = os.path.abspath(os.path.dirname(os.getcwd())) + r'case'
# case_path=os.path.join(os.getcwd(),"case")
testcase = unittest.TestSuite()
discover = unittest.defaultTestLoader.discover(case_dir,
pattern='test_*.py',
top_level_dir=None)
# discover方法筛选出来的用例,循环添加到测试套件中
# print(discover)
for test_suite in discover:
for test_case in test_suite:
# 添加用例到testcase
print(test_case)
testcase.addTest(test_case)
return testcase
if __name__ == "__main__":
# 生成测试报告格式;
# 获取当前时间
now_time = time.strftime('%Y-%m-%d %H_%M_%S')
# 测试报告生成存放路径;
file_path = os.path.abspath(os.path.dirname(os.getcwd())) + r'report' + r'Automation_Report_'+ now_time + '.html'
f = open(file_path, 'wb') # 以读写的方式打开文件;
runner = HTMLTestRunner.HTMLTestRunner(stream=f, title='专业知识点掌握情况反馈系统自动化测试报告', description='专业知识点掌握情况反馈系统自动化测试报告', verbosity=2)
runner.run(allcase())
f.close()
结语
最后到这框架介绍就结束了,这是一个简单的UI自动化框架,里面还有很多可以优化的地方;



