web-UI自动化框架实例
框架组成如下所示:
显示模块如下:Common、Conf、Outputs、PageLocators、PageObjects、TestCases、TestDatas

Common里放的是公共类,需要共同使用到的文件
basepage.py
1 import os 2 import time 3 from time import sleep 4 from selenium.webdriver.support.wait import WebDriverWait 5 from selenium.webdriver.support import expected_conditions as EC 6 from selenium.webdriver.remote.webdriver import WebDriver 7 from selenium.webdriver.common.action_chains import ActionChains 8 from Common.my_logger import logger 9 from Common.handle_path import screenshot_dir 10 11 12 class BasePage: 13 14 def __init__(self,driver:WebDriver): 15 self.win_hans = None 16 self.driver = driver 17 18 # 等待页面元素可见 19 def wait_ele_visible(self,locator,page_action,timeout=20,poll_frequency=0.5): 20 """ 21 :param locator:元素定位 22 :param page_action:页面行为,截图当中作为命名 23 :param timeout: 等待超时的时间 24 :param poll_frequency: 25 :return: 26 """ 27 logger.info("在 {} 行为,等待元素:{} 可见".format(page_action,locator)) 28 try: 29 start = time.time() 30 WebDriverWait(self.driver,timeout,poll_frequency).until(EC.visibility_of_element_located(locator)) 31 except: 32 # 输出到日志 33 logger.exception("等待元素可见失败") 34 # 失败截取当前页面 35 self.get_page_img(page_action) 36 raise 37 else: 38 end = time.time() 39 logger.info("等待元素可见成功,等待耗时为:{}".format(end - start)) 40 41 # 等待页面元素存在 42 def wait_page_contains_element(self,locator,page_action,timeout=20,poll_frequency=0.5): 43 logger.info("在 {} 行为,等待元素:{} 存在".format(page_action,locator)) 44 try: 45 start = time.time() 46 WebDriverWait(self.driver,timeout,poll_frequency).until(EC.presence_of_element_located(locator)) 47 except: 48 # 输出到日志 49 logger.exception("等待元素存在失败") 50 # 失败截取当前页面 51 self.get_page_img(page_action) 52 else: 53 end = time.time() 54 logger.info("等待元素存在成功,等待耗时为:{}".format(end - start)) 55 56 # 获取元素位置,wait 默认用的是等待元素可见,如果等待的为空,则使用等待存在的元素,否则等待可见的元素 57 def get_element(self,locator,page_action,timeout=20,poll_frequency=0.5,wait_exist=False): # locator代表元素定位 58 # 先等待元素可见或者存在 59 if wait_exist is False: # if wait是None,是False 60 self.wait_page_contains_element(locator,page_action,timeout,poll_frequency) 61 else: 62 self.wait_ele_visible(locator,page_action) 63 # 元素等待或者存在 64 logger.info("在 {} 行为,查找元素:{}".format(page_action,locator)) 65 try: 66 ele = self.driver.find_element(*locator) 67 except: 68 # 输出日志 69 logger.exception("查找元素失败") 70 # 失败截取当前页面 71 self.get_page_img(page_action) 72 raise 73 else: 74 return ele 75 76 # 点击元素操作 77 def click_element(self,locator,page_action,timeout=20,poll_frequency=0.5): 78 # 等待- 查找 79 ele = self.get_element(locator,page_action,timeout,poll_frequency) 80 # 点击 81 logger.info("在 {} 行为,点击元素:{}".format(page_action,locator)) 82 try: 83 ActionChains(self.driver).move_to_element(ele).perform() 84 sleep(1) 85 ActionChains(self.driver).click(ele).perform() 86 sleep(2) 87 except: 88 logger.exception("点击操作失败") 89 self.get_page_img(page_action) 90 raise 91 92 # 输入文本内容 93 def input_text(self,locator,page_action,value,timeout=20,poll_frequency=0.5): 94 # 等待- 查找 95 ele = self.get_element(locator,page_action,timeout,poll_frequency) 96 logger.info("在 {} 行为,给元素:{} 输入文本值: {}".format(page_action,locator,value)) 97 try: 98 ele.clear() 99 ele.send_keys(value) 100 except: 101 logger.exception("元素输入文本失败") 102 self.get_page_img(page_action) 103 raise 104 105 # 等待元素存在,并获取元素文本 106 def get_text(self,locator,page_action,timeout=20,poll_frequency=0.5): 107 ele = self.get_element(locator,page_action,timeout,poll_frequency,wait_exist=True) 108 logger.info("在 {} 行为,获取元素 {} 的文本值".format(page_action,locator)) 109 try: 110 txt = ele.text 111 except: 112 logger.exception("获取元素文本失败") 113 self.get_page_img(page_action) 114 raise 115 else: 116 logger.info("文本值为:{}".format(txt)) 117 return txt 118 119 # 获取元素属性 120 def get_attribute(self,locator,page_action,attr,timeout=20,poll_frequency=0.5): 121 ele = self.get_element(locator,page_action,timeout,poll_frequency,wait_exist=True) 122 logger.info("在 {} 行为,获取元素 {} 的属性值".format(page_action,locator)) 123 try: 124 value = ele.get_attribute(attr) 125 except: 126 logger.exception("获取元素属性失败") 127 self.get_page_img(page_action) 128 raise 129 else: 130 logger.info("属性值为:{}".format(value)) 131 return value 132 133 # 切换新窗口 134 def switch_and_close_window(self): 135 # 获取所有的窗口句柄 136 self.win_hans = self.driver.window_handles 137 if len(self.win_hans) > 1: 138 self.driver.switch_to.window(self.win_hans[-1]) 139 logger.info("获取最新窗口句柄:{},并切换到新窗口".format(self.win_hans[-1])) 140 self.driver.close() 141 logger.info("关闭当前窗口页面") 142 else: 143 # 如果等于1,则切换到当前唯一的窗口 144 self.driver.switch_to.window(self.win_hans[-1]) 145 logger.info("获取最新窗口句柄: {},并切换到新窗口".format(self.win_hans[-1])) 146 147 def switch_window(self): 148 self.win_hans = self.driver.window_handles 149 self.driver.switch_to.window(self.win_hans[-1]) 150 151 def get_page_img(self,page_action): 152 # 命名规范:{XX页面__XX操作}__截图时间.png 153 cur_time = time.strftime('%Y年%m月%d日 %H时%M分%S秒',time.localtime()) 154 file_path = os.path.join(screenshot_dir,"{}_{}.png".format(page_action,cur_time)) 155 self.driver.save_screenshot(file_path) 156 logger.info("截图保存在:{}".format(file_path))
handle_config.py
1 import os 2 from configparser import ConfigParser 3 from Common.handle_path import conf_dir 4 5 class HandleConfig(ConfigParser): 6 7 def __init__(self,file_path): 8 super(HandleConfig,self).__init__() 9 self.read(file_path,encoding="utf-8") 10 11 file_path = os.path.join(conf_dir,"config.ini") 12 conf = HandleConfig(file_path)
handle_path.py
1 import os 2 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 3 print(base_dir) 4 5 # 测试用例路径 6 case_dir = os.path.join(base_dir,"TestCases") 7 8 # 测试数据的路径 9 datas_dir = os.path.join(base_dir,"TestDatas") 10 11 # 日志路径 12 logs_dir = os.path.join(base_dir,"Outputs","logs") 13 14 # 配置文件路径 15 conf_dir = os.path.join(base_dir,"Conf") 16 17 # 页面截图路径 18 screenshot_dir = os.path.join(base_dir,"Outputs","screenshots")
my_logger.py
import os import logging from Common.handle_config import conf from Common.handle_path import logs_dir class MyLogger(logging.Logger): def __init__(self,name,level=logging.INFO,file=None): super().__init__(name,level) fmt = "%(asctime)s %(name)s %(levelname)s %(filename)s-%(lineno)d行:%(message)s " formatter = logging.Formatter(fmt) handle1 = logging.StreamHandler() handle1.setFormatter(formatter) self.addHandler(handle1) if file: handle2 = logging.FileHandler(file,encoding="utf-8") handle2.setFormatter(formatter) self.addHandler(handle2) if conf.getboolean("log","file_ok"): file_name = os.path.join(logs_dir,conf.get("log","file_name")) else: file_name = None logger = MyLogger(conf.get("log","name"),conf.get("log","level"),file_name)
Conf里放置配置文件
config.ini
[log] name = log level = INFO file_ok = True file_name = testlog.log
PageLocators里放的是页面的元素定位,使用xpath定位
enter_page_loc.py
1 from selenium.webdriver.common.by import By 2 3 4 class EnterPageLoc: 5 # 退出按钮 6 exit_loc = (By.XPATH, '//a[@class="top-user-logout"]')
fp_page_loc.py
1 from selenium.webdriver.common.by import By 2 3 class FpPageLocs: 4 """ 5 页面按钮 6 """ 7 # 下载按钮 8 download_loc = (By.XPATH, '//a[text()="下载"]') 9 # ax版本下载最新版 10 ax_download_loc = (By.XPATH, '//h3[text()="Adobe Flash Player ActiveX版"]/following-sibling::a[text()="下载最新版"]') 11 # pp版本下载最新版 12 pp_download_loc = (By.XPATH, '//h3[text()="Adobe Flash Player PPAPI版"]/following-sibling::a[text()="下载最新版"]') 13 # np版本下载最新版 14 np_download_loc = (By.XPATH, '//h3[text()="Adobe Flash Player NPAPI版"]/following-sibling::a[text()="下载最新版"]') 15 # MAC pp下载 16 mac_pp_download_loc = (By.XPATH, '//a[@href="https://www.flash.cn/flashplayer/latest/install_flash_player_osx_ppapi.dmg"]') 17 # MAC np下载 18 mac_np_download_loc = (By.XPATH, '//a[@href="https://www.flash.cn/flashplayer/latest/install_flash_player_osx.dmg"]') 19 # 咨询客服 20 customer_loc = (By.XPATH, '//a[text()="咨询客服"]')
home_page_loc.py
1 from selenium.webdriver.common.by import By 2 3 class HomePageLocs: 4 """ 5 页面按钮 6 """ 7 # 立即下载按钮 8 fc_download_loc = (By.XPATH, '//a[text()="立即下载"]') 9 # Adobe Flash Player下载 文本点击 10 fp_download_loc = (By.XPATH, '//a[text()="Adobe Flash Player下载"]') 11 # 企业版链接跳转 12 ep_download_loc = (By.XPATH, '//a[text()="企业版授权下载"]') 13 # 导航栏按钮 14 # 首页 15 home_loc = (By.XPATH, '//a[text()="首页"]') 16 # flash中心 17 flash_center_loc = (By.XPATH, '//a[text()="Flash中心"]') 18 # 企业版 19 enterprise_loc = (By.XPATH, '//a[text()="企业版"]') 20 # 教育版 21 education_loc = (By.XPATH, '//a[text()="教育版"]') 22 # 帮助中心 23 help_center_loc = (By.XPATH, '//a[text()="帮助中心"]') 24 # 客服支持 25 custom_service_loc = (By.XPATH, '//a[text()="客服支持"]') 26 # 官方公告 27 notice_item_loc = (By.XPATH, '//a[text()="官方公告"]')
login_page_loc.py
1 from selenium.webdriver.common.by import By 2 3 class LoginPageLocs: 4 5 # 用户名输入框 6 username_loc = (By.XPATH, '//input[@class="en-log-name"]') 7 # 密码输入框 8 passwd_loc = (By.XPATH, '//input[@class="en-log-password"]') 9 # 登录按钮 10 login_button_loc = (By.XPATH, '//span[@class="en-log-btn"]') 11 # 用户名下方提示语 12 user_prompt_box_loc = (By.XPATH,'//input[@class="en-log-name"]/parent::div[@class="en-log-item"]/following-sibling::p') 13 # 密码下方提示语 14 pwd_prompt_box_loc = (By.XPATH,'//input[@class="en-log-password"]/parent::div[@class="en-log-item"]/following-sibling::p')
PageObjects里放的是页面元素的操作内容
close_window.py
1 from Common.basepage import BasePage 2 3 class CloseWins(BasePage): 4 5 def close_wins_handle(self): 6 self.switch_and_close_window() 7 8 def switch_wins_handle(self): 9 self.switch_window()
enter_page.py
1 from PageLocators.enter_page_loc import EnterPageLoc as loc 2 from Common.basepage import BasePage 3 4 class EnterPage(BasePage): 5 # 判断退出按钮存在 6 def is_exit_exist(self): 7 try: 8 self.wait_ele_visible(loc.exit_loc,"首页_等待退出元素可见") 9 except: 10 return False 11 else: 12 return True
fp_page.py
1 from time import sleep 2 from PageLocators.fp_page_loc import FpPageLocs as loc 3 from Common.basepage import BasePage 4 from Common.my_logger import logger 5 6 class FpPage(BasePage): 7 8 def click_download_loc(self): 9 sleep(2) 10 logger.info("开始进行:点击flash player页面_下载按钮操作") 11 return self.click_element(loc.download_loc,"flash player页面_下载按钮") 12 13 def click_ax_download_loc(self): 14 sleep(2) 15 logger.info("开始进行:点击flash player页面_ax版本下载按钮操作") 16 return self.click_element(loc.ax_download_loc,"flash player页面_ax版本下载按钮") 17 18 def click_pp_download_loc(self): 19 sleep(2) 20 logger.info("开始进行:点击flash player页面_pp版本下载按钮操作") 21 return self.click_element(loc.pp_download_loc,"flash player页面_pp版本下载按钮") 22 23 def click_np_download_loc(self): 24 sleep(2) 25 logger.info("开始进行:点击flash player页面_np版本下载按钮操作") 26 return self.click_element(loc.np_download_loc,"flash player页面_np版本下载按钮") 27 28 def click_mac_pp_download_loc(self): 29 sleep(2) 30 logger.info("开始进行:点击flash player页面_mac-pp版本下载按钮操作") 31 return self.click_element(loc.mac_pp_download_loc,"flash player页面_mac-pp版本下载按钮") 32 33 def click_mac_np_download_loc(self): 34 sleep(2) 35 logger.info("开始进行:点击flash player页面_mac-np版本下载按钮操作") 36 return self.click_element(loc.mac_np_download_loc,"flash player页面_mac-np版本下载按钮") 37 38 def click_customer_loc(self): 39 sleep(2) 40 logger.info("开始进行:点击flash player页面_咨询客服按钮操作") 41 return self.click_element(loc.customer_loc,"flash player页面_咨询客服")
home_page.py
1 from time import sleep 2 from PageLocators.home_page_loc import HomePageLocs as loc 3 from Common.basepage import BasePage 4 from Common.my_logger import logger 5 6 class HomePage(BasePage): 7 8 def click_fc_download_loc(self): 9 sleep(2) 10 logger.info("开始进行:点击首页页面_fc下载按钮操作") 11 return self.click_element(loc.fc_download_loc,"首页页面_fc下载按钮") 12 13 def click_fp_download_loc(self): 14 sleep(2) 15 logger.info("开始进行:点击首页页面_flash player下载文本操作") 16 return self.click_element(loc.fp_download_loc,"首页页面_flash player下载文本") 17 18 def click_ep_download_loc(self): 19 sleep(2) 20 logger.info("开始进行:点击首页页面_企业版下载文本操作") 21 return self.click_element(loc.ep_download_loc,"首页页面_企业版下载文本") 22 23 def click_flash_center_loc(self): 24 sleep(2) 25 logger.info("开始进行:点击首页页面_导航栏flash中心操作") 26 return self.click_element(loc.flash_center_loc,"首页页面_导航栏flash中心") 27 28 def click_enterprise_loc(self): 29 sleep(2) 30 logger.info("开始进行:点击首页页面_导航栏企业版操作") 31 return self.click_element(loc.enterprise_loc,"首页页面_导航栏企业版") 32 33 def click_education_loc(self): 34 sleep(2) 35 logger.info("开始进行:点击首页页面_导航栏教育版操作") 36 return self.click_element(loc.education_loc,"首页页面_导航栏教育版") 37 38 def click_help_center_loc(self): 39 sleep(2) 40 logger.info("开始进行:首页页面_导航栏帮助中心操作") 41 return self.click_element(loc.help_center_loc,"首页页面_导航栏帮助中心") 42 43 def click_custom_service_loc(self): 44 sleep(2) 45 logger.info("开始进行:点击首页页面_导航栏客服支持操作") 46 return self.click_element(loc.custom_service_loc,"首页页面_导航栏客服支持") 47 48 def click_notice_item_loc(self): 49 sleep(2) 50 logger.info("开始进行:首页页面_导航栏官方公告操作") 51 return self.click_element(loc.notice_item_loc,"首页页面_导航栏官方公告") 52 53 def back_last_page(self): 54 sleep(2) 55 logger.info("开始进行:返回上一个页面操作") 56 return self.driver.back()
login_page.py
1 from time import sleep 2 from PageLocators.login_page_loc import LoginPageLocs as loc 3 from Common.basepage import BasePage 4 5 class LoginPage(BasePage): 6 7 def login(self,user,passwd): 8 self.input_text(loc.username_loc,"登录页面_输入用户名",user) 9 self.input_text(loc.passwd_loc,"登录页面_输入密码",passwd) 10 self.click_element(loc.login_button_loc,"登录页面_点击登录按钮") 11 12 # 获取用户名输入错误时的提示框 13 def get_error_user_msg_from_login_area(self): 14 # 等待2s,使得元素文本显示 15 sleep(2) 16 return self.get_text(loc.user_prompt_box_loc,"登录页面_用户名下方错误提示信息") 17 18 # 获取密码输入错误时的提示框 19 def get_error_pwd_msg_from_login_area(self): 20 # 等待2s,使得元素文本显示 21 sleep(2) 22 return self.get_text(loc.pwd_prompt_box_loc,"登录页面_密码下方错误提示信息")
TestDatas里放的测试用例要用到的一些数据
global_data.py
1 import os 2 3 base_url = "https://www.flash.cn/" 4 5 # 登录页面地址 6 login_url = os.path.join(base_url,"enterprise/login.html") 7 8 # fp页面地址 9 fp_url = os.path.join(base_url,"download-wins") 10 11 12 # 通用的普通用户 13 user = ("15618275180","123456")
login_data.py
1 valid_user = ("15618275180","123456") 2 3 invalid_data_user = [ 4 {"user": "15618275181", "passwd": "123456", "check": "用户名不存在或密码不正确"}, 5 {"user": "15618275180", "passwd": "12345678", "check": "用户名不存在或密码不正确"}, 6 {"user": "15618278956", "passwd": "123456", "check": "用户名不存在或密码不正确"}, 7 {"user": "", "passwd": "123456", "check": "手机号不能为空"} 8 ] 9 10 invalid_data_pwd = [{"user": "15618275180", "passwd": "", "check": "密码不能为空"}]
TestCases里放置测试用例
使用fixture时,会有个conftest文件
conftest.py
1 import pytest 2 from selenium import webdriver 3 from TestDatas import global_data as gd 4 from selenium.webdriver.chrome.service import Service 5 from webdriver_manager.chrome import ChromeDriverManager 6 7 # 实例化driver,访问登录页面 8 s = Service(ChromeDriverManager().install()) 9 options = webdriver.ChromeOptions() 10 prefs = {'download.prompt_for_download': False, 'download.default_directory': r'C:\Users\Any\Downloads', } 11 options.add_experimental_option("prefs", prefs) 12 driver = webdriver.Chrome(chrome_options=options, service=s) 13 driver.maximize_window() 14 driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command') 15 params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': r"C:\Users\2144\Downloads"}} 16 driver.execute("send_command", params) 17 18 # 定义testfp的fixture- 前置后置 - 作用域 - 返回值 19 @pytest.fixture(scope="class") 20 def testfp_init(): 21 driver.get(gd.fp_url) 22 yield driver 23 driver.quit() 24 @pytest.fixture() 25 def testfp_back(testfp_init): 26 driver.get(gd.fp_url) 27 yield testfp_init 28 29 30 # 定义testfp的fixture- 前置后置 - 作用域 - 返回值 31 @pytest.fixture(scope="class") 32 def testlogin_init(): 33 driver.get(gd.login_url) 34 yield driver 35 # driver.quit() 36 @pytest.fixture() 37 def testlogin_back(testlogin_init): 38 driver.get(gd.login_url) 39 yield testlogin_init 40 41 42 # 定义testfp的fixture- 前置后置 - 作用域 - 返回值 43 @pytest.fixture(scope="class") 44 def testhome_init(): 45 driver.get(gd.base_url) 46 yield driver 47 # driver.quit() 48 @pytest.fixture() 49 def testhome_back(testhome_init): 50 driver.get(gd.base_url) 51 yield testhome_init
test_fp.py
1 import allure 2 import pytest 3 from PageObjects.fp_page import FpPage 4 from Common.my_logger import logger 5 6 @pytest.mark.run(order=3) 7 # @allure.feature("flash官网flash player详情页面-测试文本链接点击跳转功能") 8 @pytest.mark.usefixtures("testfp_back") 9 class TestFP: 10 11 # @allure.story("点击flash player页面下载按钮-用例") 12 def test_click_fp_1(self, testfp_back): 13 try: 14 # 点击下载按钮 15 FpPage(testfp_back).click_download_loc() 16 except: 17 logger.exception("当前用例执行失败,点击页面有报错\n") 18 raise 19 else: 20 logger.info("当前用例执行成功,页面点击跳转成功\n") 21 22 # @allure.story("点击flash player页面ax版本下载按钮-用例") 23 def test_click_fp_2(self, testfp_back): 24 try: 25 # 点击ax版本下载按钮 26 FpPage(testfp_back).click_ax_download_loc() 27 except: 28 logger.exception("当前用例执行失败,点击页面有报错\n") 29 raise 30 else: 31 logger.info("当前用例执行成功,页面点击跳转成功\n") 32 33 # @allure.story("点击flash player页面pp版本下载按钮-用例") 34 def test_click_fp_3(self, testfp_back): 35 try: 36 # 点击pp版本下载按钮 37 FpPage(testfp_back).click_pp_download_loc() 38 except: 39 logger.exception("当前用例执行失败,点击页面有报错\n") 40 raise 41 else: 42 logger.info("当前用例执行成功,页面点击跳转成功\n") 43 44 # @allure.story("点击flash player页面np版本下载按钮-用例") 45 def test_click_fp_4(self, testfp_back): 46 try: 47 # 点击np版本下载按钮 48 FpPage(testfp_back).click_np_download_loc() 49 except: 50 logger.exception("当前用例执行失败,点击页面有报错\n") 51 raise 52 else: 53 logger.info("当前用例执行成功,页面点击跳转成功\n") 54 55 # @allure.story("点击flash player页面mac-pp版本下载按钮-用例") 56 def test_click_fp_5(self, testfp_back): 57 try: 58 # 点击mac-pp版本下载按钮 59 FpPage(testfp_back).click_mac_pp_download_loc() 60 except: 61 logger.exception("当前用例执行失败,点击页面有报错\n") 62 raise 63 else: 64 logger.info("当前用例执行成功,页面点击跳转成功\n") 65 66 # @allure.story("点击flash player页面mac-np版本下载按钮-用例") 67 def test_click_fp_6(self, testfp_back): 68 try: 69 # 点击mac-np版本下载按钮 70 FpPage(testfp_back).click_mac_np_download_loc() 71 except: 72 logger.exception("当前用例执行失败,点击页面有报错\n") 73 raise 74 else: 75 logger.info("当前用例执行成功,页面点击跳转成功\n") 76 77 # @allure.story("flash player页面_咨询客服按钮-用例") 78 def test_click_fp_7(self, testfp_back): 79 try: 80 # 点击首页导航栏-客服支持 81 FpPage(testfp_back).click_customer_loc() 82 except: 83 logger.exception("当前用例执行失败,点击页面有报错\n") 84 raise 85 else: 86 logger.info("当前用例执行成功,页面点击跳转成功\n")
test_home.py
1 import allure 2 import pytest 3 from PageObjects.home_page import HomePage 4 from PageObjects.close_window import CloseWins 5 from Common.my_logger import logger 6 7 @pytest.mark.run(order=2) 8 # @allure.feature("flash官网首页-测试文本链接点击跳转功能") 9 @pytest.mark.usefixtures("testhome_back") 10 class TestHome: 11 12 # @allure.story("点击首页-立即下载按钮-用例") 13 def test_click_home_1(self,testhome_back): 14 try: 15 # 点击首页-立即下载按钮 16 HomePage(testhome_back).click_fc_download_loc() 17 except: 18 logger.exception("当前用例执行失败,点击页面有报错\n") 19 raise 20 else: 21 logger.info("当前用例执行成功,页面点击跳转成功\n") 22 23 # @allure.story("点击flash player下载文本链接-用例") 24 def test_click_home_2(self, testhome_back): 25 try: 26 # 点击flash player下载文本链接 27 HomePage(testhome_back).click_fp_download_loc() 28 # 获取新窗口句柄并切换到新窗口,然后关闭当前窗口 29 CloseWins(testhome_back).close_wins_handle() 30 # 获取当前窗口的句柄 31 CloseWins(testhome_back).close_wins_handle() 32 except: 33 logger.exception("当前用例执行失败,点击页面有报错\n") 34 raise 35 else: 36 logger.info("当前用例执行成功,页面点击跳转成功\n") 37 38 # @allure.story("点击企业版授权下载文本链接-用例") 39 def test_click_home_3(self, testhome_back): 40 try: 41 # 点击企业版授权下载文本链接 42 HomePage(testhome_back).click_ep_download_loc() 43 # 获取新窗口句柄并切换到新窗口,然后关闭当前窗口 44 CloseWins(testhome_back).close_wins_handle() 45 # 获取当前窗口的句柄 46 CloseWins(testhome_back).close_wins_handle() 47 except: 48 logger.exception("当前用例执行失败,点击页面有报错\n") 49 raise 50 else: 51 logger.info("当前用例执行成功,页面点击跳转成功\n") 52 53 # @allure.story("点击首页导航栏-flash中心文本-用例") 54 def test_click_home_4(self, testhome_back): 55 try: 56 # 点击首页导航栏-flash中心文本链接 57 HomePage(testhome_back).click_flash_center_loc() 58 # 获取新窗口句柄并切换到新窗口,然后关闭当前窗口 59 CloseWins(testhome_back).close_wins_handle() 60 # 获取当前窗口的句柄 61 CloseWins(testhome_back).close_wins_handle() 62 except: 63 logger.exception("当前用例执行失败,点击页面有报错\n") 64 raise 65 else: 66 logger.info("当前用例执行成功,页面点击跳转成功\n") 67 68 # @allure.story("点击首页导航栏-企业版文本-用例") 69 def test_click_home_5(self, testhome_back): 70 try: 71 # 点击首页导航栏-企业版文本 72 HomePage(testhome_back).click_enterprise_loc() 73 # 返回上一页 74 HomePage(testhome_back).back_last_page() 75 except: 76 logger.exception("当前用例执行失败,点击页面有报错\n") 77 raise 78 else: 79 logger.info("当前用例执行成功,页面点击跳转成功\n") 80 81 # @allure.story("点击首页导航栏-教育版文本-用例") 82 def test_click_home_6(self, testhome_back): 83 try: 84 # 点击首页导航栏-教育版文本 85 HomePage(testhome_back).click_education_loc() 86 # 返回上一页 87 HomePage(testhome_back).back_last_page() 88 except: 89 logger.exception("当前用例执行失败,点击页面有报错\n") 90 raise 91 else: 92 logger.info("当前用例执行成功,页面点击跳转成功\n") 93 94 # @allure.story("点击首页导航栏-帮助中心-用例") 95 def test_click_home_7(self, testhome_back): 96 try: 97 # 点击首页导航栏-帮助中心 98 HomePage(testhome_back).click_help_center_loc() 99 # 返回上一页 100 HomePage(testhome_back).back_last_page() 101 except: 102 logger.exception("当前用例执行失败,点击页面有报错\n") 103 raise 104 else: 105 logger.info("当前用例执行成功,页面点击跳转成功\n") 106 107 # @allure.story("点击首页导航栏-客服支持-用例") 108 def test_click_home_8(self, testhome_back): 109 try: 110 # 点击首页导航栏-客服支持 111 HomePage(testhome_back).click_custom_service_loc() 112 # 返回上一页 113 HomePage(testhome_back).back_last_page() 114 except: 115 logger.exception("当前用例执行失败,点击页面有报错\n") 116 raise 117 else: 118 logger.info("当前用例执行成功,页面点击跳转成功\n") 119 120 # @allure.story("点击首页导航栏-官方公告-用例") 121 def test_click_home_9(self, testhome_back): 122 # 点击首页导航栏-官方公告 123 try: 124 HomePage(testhome_back).click_notice_item_loc() 125 except: 126 logger.exception("当前用例执行失败,点击页面有报错\n") 127 raise 128 else: 129 logger.info("当前用例执行成功,页面点击跳转成功\n")
test_login.py
1 import allure 2 import pytest 3 from PageObjects.login_page import LoginPage 4 from PageObjects.enter_page import EnterPage 5 from TestDatas import login_data as ld 6 from Common.my_logger import logger 7 8 9 @pytest.mark.run(order=1) 10 # @allure.feature("企业版登录页面-测试用户登录功能") 11 @pytest.mark.usefixtures("testlogin_back") 12 class TestLogin: 13 # 异向场景 - 登录失败 - 数据格式无效 14 15 # @allure.story("登录功能-用户名下方错误提示用例") 16 @pytest.mark.parametrize("case",ld.invalid_data_user) 17 def test_login_fail_invalid_data_user(self,case,testlogin_back): 18 LoginPage(testlogin_back).login(case["user"],case["passwd"]) 19 try: 20 assert LoginPage(testlogin_back).get_error_user_msg_from_login_area() == case["check"] 21 except: 22 logger.exception("当前用例执行失败,断言不通过\n") 23 else: 24 logger.info("当前用例执行成功,断言通过\n") 25 26 # @allure.story("登录功能-密码下方错误提示用例") 27 @pytest.mark.parametrize("case",ld.invalid_data_pwd) 28 def test_login_fail_invalid_data_pwd(self,case,testlogin_back): 29 LoginPage(testlogin_back).login(case["user"],case["passwd"]) 30 try: 31 assert LoginPage(testlogin_back).get_error_pwd_msg_from_login_area() == case["check"] 32 except: 33 logger.exception("当前用例执行失败,断言不通过\n") 34 else: 35 logger.info("当前用例执行成功,断言通过\n") 36 37 # 正向场景 - 登录成功 38 # @allure.story("登录功能-登录成功用例") 39 def test_login_success(self,testlogin_back): 40 LoginPage(testlogin_back).login(*ld.valid_user) 41 try: 42 assert EnterPage(testlogin_back).is_exit_exist() 43 except: 44 logger.exception("当前用例执行失败,断言不通过\n") 45 else: 46 logger.info("当前用例执行成功,断言通过\n")
main.py,执行所有测试用例的总入口
1 import pytest 2 3 if __name__ == '__main__': 4 pytest.main(["-s", "-v", "--html=Outputs/html/pytest.html", "--alluredir=Outputs/allure"])
测试输出报告内容如下:
allure- allure文件
html- html类型的测试报告
report- allure测试报告
logs- 执行用例过程中的日志
screenshots- 报错截图
然后到jenkins中开始构建,生成allure报告
本文来自博客园,作者:夏末雨季,转载请注明原文链接:https://www.cnblogs.com/shan-shan/articles/15951428.html

浙公网安备 33010602011771号