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报告

posted @ 2022-03-01 17:28  夏末雨季  阅读(97)  评论(0)    收藏  举报