unittest 运行slenium(三)---通过数据驱动形式运行用例
一: 获取数据
获取用例所在位置,通过OpenExcelPandas来读取用例里面的全部数据。通过某个列名来创建新的序号。
并将结果转换成list类型,将其作为ddt数据的来源。
1. 在test文件中调用数据驱动准备函数
excel_data = user_login.excel_to_list(user_login.login_excel, user_login.login_sheet, '序号')
2. 根据指定的用例来读取数据并转换成list
def get_ini_file(excel: str) -> str: # 文件参数路径 argument = ReadModelIni(ini_name) # yaml读取用例位置 login_path = argument.get_value(cd_excel, cd_login) module_path = argument.get_value(cd_excel, excel) module_excel_path = os.path.join(login_path, module_path) return module_excel_path def excel_to_list(excel: str, sheet: str, title_name: str) -> list: """ 读取用例 :return: 将数据转换成list进行返回 """ excel_path = get_ini_file(excel) # 读取相应路径中的数据 read = OpenExcelPandas(name=excel_path, sheet=sheet) ex_data = read.internal_read_excel(title_name) df_index = ex_data.index ex_data = [ex_data.loc[df_i] for df_i in df_index] return ex_data
二: 创建test
1. 类装饰器为@ddt.ddt
2. test函数装饰器为@ddt.data
3. 在test运行前需要创建test的操作类对象,并实例化日志对象。
4. 具体代码
import os import inspect import unittest import ddt from case.zentao import user_login from business.zentao.login.user_login_business import UserLoginBusiness base_path = os.path.split(os.path.dirname(__file__))[1] base_name = base_path + "-" + os.path.splitext(os.path.basename(__file__))[0] excel_data = user_login.excel_to_list(user_login.login_excel, user_login.login_sheet, '序号') @ddt.ddt class TestLoginUser(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.business_login = UserLoginBusiness(base_name) pass def setUp(self) -> None: self.business_login.create_browser() pass def tearDown(self) -> None: self.business_login.login_page.browser_action.close_driver_browser() pass @ddt.data(*excel_data) def test_run_login(self, case): self.business_login.log.info("%s序号的用例开始运行" % case["序号"]) # 设置日志需要输出的函数名 self.business_login.log.fun_name = "%s-%s" % (inspect.stack()[0][3], case["序号"]) # 打印需要输出的内容 # self.business_login.log.info("用例中所以的内容为:%s" % case) # 定义第三方存储对象,可以让其它对象进行调用使用。 self.business_login.data_case_singe = case # 运行执行用例需要执行的动作 self.business_login.user_pass_error() self.business_login.log.info("%s序号的用例运行完毕" % case["序号"]) pass if __name__ == '__main__': unittest.main(verbosity=2) del excel_data
三: 创建page元素类
1. 该类存储当前页面所有的元素所在路径及路径类型
2. 在实例化时创建浏览器对象
3. 代码如下:
from util_tools.operation.action_interface import ActionParsing class UserLoginPage(object): def __init__(self): self.browser_action = ActionParsing() pass def input_user_name(self, parameter) -> None: """ 返回账号元素的类型及路径 :return: """ account = "id>>account" self.browser_action.is_input_execute(account, parameter) pass def input_pass_word(self, parameter) -> None: """ 返回密码元素的类型及路径 :return: """ pass_word = "css>>input[type=password]" self.browser_action.is_input_execute(pass_word, parameter) pass def click_login_button(self) -> None: """ 返回登录按钮元素的类型及路径 :return: """ button = "css>>.btn.btn-primary" self.browser_action.is_click_execute(button) pass def get_form_error(self) -> str: """ 返回登录错误时系统弹窗提示语的类型及路径 :return: """ # form_error = "id>>formError" # attr_text = self.browser_action.get_text_value(form_error) # 获取弹窗对象 alert_pupop = self.browser_action.driver.switch_to.alert # 获取弹窗内容 alert_text = alert_pupop.text # 点击弹窗中的确定按钮 alert_pupop.accept() return alert_text pass
四:test用例操作类
1. 该类主要是对用例执行的进行操作
2. 代码如下
from selenium.webdriver.support import expected_conditions as EC from util_tools.logger import Logger from util_tools.storage.read_model_file import ReadModelIni from pages.zentao.login.user_login_page import UserLoginPage from case.zentao import user_login class UserLoginBusiness(object): def __init__(self, base_name: str): """ 实例化对象,并且创建日志对象及元素操作对象 :param base_name: 用例运行类类名 """ self.log = Logger(base_name) self.login_page = UserLoginPage() pass # ----------------- 将set跟get封装后由单个参数来实现 ----------------- def set_case(self, case): self.case = case pass def get_case(self): return self.case data_case_singe = property(get_case, set_case, doc="找不到内容") # ----------------- ----------------- def create_browser(self): # 获取需要打开的url argument = ReadModelIni("system_settings.ini") login_url = argument.get_value("wap_url", "zen_tao_url") self.log.info("浏览器url :" + login_url) # 创建浏览器对象,并打开 self.login_page.browser_action.run_web_browser(login_url, user_login.login_browser, user_login.login_wait_time) self.log.info("%s浏览器已经打开,显示时间为%ss" % (user_login.login_browser, user_login.login_wait_time)) def user_pass_error(self): # 执行账号输入操作 self.login_page.input_user_name(self.data_case_singe["账号"]) # 执行密码输入操作 self.login_page.input_pass_word(self.data_case_singe["密码"]) # 判断是否需要点击登录按钮 login_button = self.data_case_singe["登录"] if login_button.capitalize() in 'Y': # 执行点击操作 self.login_page.click_login_button() # 判断点击登录后的情况 login_follow = self.data_case_singe["后续"] login_follow_label, login_follow_info = login_follow.split("-->") if 'error' in login_follow_label: # 账号密码错误时,提示语的判断。 attr_text = self.login_page.get_form_error() assert attr_text in login_follow_info, "登录失败时,提示语判断错误。" self.log.info("登录失败的原因为:%s" % login_follow_info) pass elif 'go' in login_follow_label: # 点击登录后跳转的页面 assert EC.title_contains(login_follow_info), "页面已经发生跳转并不在登录页面" pass else: self.log.info("点击登录后,excel中的后续编写有误:%s" % login_follow) pass else: self.log.info("不需要点击登录按钮") pass pass
项目所在位置: