UI自动化python中selenium二次封装+参数化调用笔记

#第一步:1.在base目录内建文件名base_page.py
封装【基类行为】和【驱动工具类】

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
import config
#1#封装【驱动工具】
class Driver_Tools:
    driver=None#用于保存driver数据初值None
    @classmethod
    def create(cls):
        if cls.driver is None:#如果driver为None不存在执行
            cls.driver = webdriver.Chrome()
            cls.driver.maximize_window()
        return cls.driver#返回drive值
    @classmethod
    def quit(cls):
        if cls.driver is not None:#如果driver为not None存在执行
            cls.driver.quit()
            cls.driver=None#健壮性
            # 为了满足create方法中if条件的is None
# 2#封装获取截图的函数
def get_screenshot(key):
    filename = time.strftime("%Y%m%d-%H%M%S") + ".png"
    filepath = config.D + "/screenshot/" + key +filename
    Driver_Tools.create().get_screenshot_as_file(f"{filepath}")
#3#封装动作
class Base_Page:
    def __init__(self):#创建驱动
        self.driver=Driver_Tools.create()
    # 1查找元素
    # def find_el(self,loc):#loc元组(By.ID,XXX)形参定位元素
    def find_el(self,loc,timeout=10):#loc元组(By.ID,XXX)形参定位元素
        # loc = (By.ID, "userA")定位元素位置
        try:  # 显式等待#函数名=lambda 形参:函数体# 显式等待#函数名=lambda 形参:函数体*元组拆包
            el = WebDriverWait(self.driver, timeout).until(lambda x: x.find_element(*loc))
            return el
        except Exception as e:
            print(f"{loc}元素没有找到~!")
            # return e
            raise e # 注意 raise后不可以return了
            # return False

    # 2 输入内容方法
    def input_text(self,loc,text,timeout=10):
        #loc元组(By.ID,XXX)形参定位元素
        # text形参loc元组定位元素后输入text数据
        self.find_el(loc,timeout).clear()#清除loc元组文本数据
        self.find_el(loc,timeout).send_keys(text)#输入文本数据

    # 3 点击方法
    def click_el(self,loc,timeout=10):#loc元组(By.ID,XXX)形参定位元素
        self.find_el(loc,timeout).click()#点击数据

    # 4 打开网页的方法
    def open_url(self,url):#url形参用于传参网址
        self.driver.get(url)#打开url网站

    # 5.1切换iframe的方法
    def switch_frame(self,loc,timeout=10):
        # 定位iframe元素
        iframe_el=self.find_el(loc,timeout)
        # 切换iframe
        self.driver.switch_to.frame(iframe_el)
    # 5.2切回iframe的方法
    def parent_frame(self):
        self.driver.switch_to.parent_frame()  # 返回上一级iframe并重新定位iframe位置
    # 5.3 恢复原始iframe的方法
    def default_content_frame(self):
        self.driver.switch_to.default_content()#恢复默认iframe并重新定位iframe位置

    # 6 获取弹出框文本的方法
    def get_tips_msg(self,loc,timeout=10):
        #调用显示等待查找元素find_el的文本text返回结果
        tips=self.find_el(loc,timeout).text
        return tips

    #7封装下拉框
    def select_option(self,loc,text):
        select=Select(self.find_el(loc))
        select.select_by_visible_text(text)

#第二步:2.在page目录内建文件名htlogin_page.py
#封装打开并【登录】

from selenium.webdriver.common.by import By
# 1分析登录页面>定义登录类>继承基类
from base.base_page import Base_Page, Driver_Tools
class Login_Page(Base_Page):
    def __init__(self):  # 2分析元素
        super().__init__()  # 重写扩展
        # self.driver=DriverTools.create()#省略调用固定驱动
        self.username = (By.NAME, 'username')  # 2定位账号元素
        self.password = (By.NAME, 'password')  # 3定位密码元素
        self.verify = (By.NAME, 'vertify')  # 4定位验证码元素
        self.sbtbutton = (By.NAME, 'submit')  # 5定位登录按钮元素
        # 6定位弹出框文本元素
        self.i_loc = (By.CSS_SELECTOR, ".layui-layer-content")
    # 3分析业务行为1打开网站#打开首页页面#定义行为函数【登录首页】
    def open_index(self):
        # 1)打开【首页】网站
        self.open_url("http://hmshop-test.itheima.net/Admin")
    # 3.1分析业务行为输入数据点击登录按钮#定义行为【登录】函数
    def Iogin_data(self, username, password, verify):
        # 1输入#账号
        self.input_text(self.username, username)
        # 2输入#密码
        self.input_text(self.password, password)
        # 3输入#验证码
        self.input_text(self.verify, verify)
        # 4点击【登录】按钮
        self.click_el(self.sbtbutton)
    # 3.2分析业务行为点击登录按钮后弹出框文本
    def get_tips(self):#封装【弹出框】方法2
        # 调用基类弹出框文本传弹出框文本元素返回值
        te=self.get_tips_msg(self.i_loc)
        return te

#第三步:3.在page目录内建文件名htindex_page.py
#封装【首页】点击商城

from selenium.webdriver.common.by import By
# from page.fzbase import Base_Page#导包基类
#1分析首页页面>定义首页类>继承基类
from base.base_page import Base_Page, Driver_Tools
from page.htlogin_page import Login_Page
class Index_Page(Base_Page):
    def __init__(self):#2分析元素
        # #__init__实例属性
        super().__init__()#重写扩展
        # self.driver=DriverTools.create()#省略调用固定驱动
        # 1定位商城元素
        self.shop_loc=(By.LINK_TEXT, "商城")
        self.get_loc= (By.CSS_SELECTOR, "span.bgdopa-t")
    def go_shop(self):
        # 1)点击【商城】超链接
        self.click_el(self.shop_loc)
    def get_text(self):
        # 1)点击【商城】超链接
        return self.find_el(self.get_loc).text

#第四步:4.在page目录内建文件名htshopping_page.py
#进入新增商品页

from selenium.webdriver.common.by import By
#1分析商城页面>定义商城类>继承基类
from base.base_page import Base_Page, Driver_Tools
from page.htindex_page import Index_Page
from page.htlogin_page import Login_Page
class Shop_Page(Base_Page):
    def __init__(self):#2分析元素
        # #__init__实例属性htshopping_page.py
        super().__init__()#重写扩展
        # self.driver=DriverTools.create()#省略调用固定驱动
        # 1定位商城元素
        # 2)添加商品
        self.add_goods_loc = By.XPATH, "//div[@title='添加商品']"
        # 3)首个商品名称
        self.first_goods_loc = By.XPATH, '//div[@id="flexigrid"]//td[4]/div'
        # 4)frame元素
        self.iframe_loc = By.ID, "workspace"
        #显示登录用户文本
    def get_shop_msg(self):
        self.switch_frame(self.iframe_loc)
        text= self.find_el(self.first_goods_loc).text
        self.parent_frame()
        return text
    # 进入新增商品页
    def add_shop_page(self):
        self.switch_frame(self.iframe_loc)
        self.click_el(self.add_goods_loc)
        self.parent_frame()

#第五步:5.在page目录内建文件名htadd_product_page.py
#封装添加商品信息

from selenium.webdriver.common.by import By
#1分析添加商品页面>定义添加商品类>继承基类
from base.base_page import Base_Page, Driver_Tools
from page.htindex_page import Index_Page
from page.htlogin_page import Login_Page
from page.htshopping_page import Shop_Page
class Add_Page(Base_Page):
    def __init__(self):
        super().__init__()
        # 新增商品frame
        self.product_iframe_loc = By.ID, "workspace"
        # 商品名称
        self.product_name_loc = By.CSS_SELECTOR, "input[name='goods_name']"
        # 商品一级分类select
        self.cat_1_loc = By.CSS_SELECTOR, 'select[id="cat_id"]'
        # 商品二级分类select
        self.cat_2_loc = By.CSS_SELECTOR, 'select[id="cat_id_2"]'
        # 商品三级分类select
        self.cat_3_loc = By.CSS_SELECTOR, 'select[id="cat_id_3"]'
        # 本店售价
        self.shop_price_loc = By.CSS_SELECTOR, "input[name='shop_price']"
        # 市场售价
        self.market_price_loc = By.CSS_SELECTOR, "input[name='market_price']"
        # 运费模版
        self.template_loc = By.CSS_SELECTOR, "select[name='template_id']"
        # 商品详情iframe
        self.ueditor_iframe_Loc = By.CSS_SELECTOR, "iframe#ueditor_0"
        # 商品详情编辑框
        self.content_loc = By.CSS_SELECTOR, "body.view"
        # 确认提交
        self.submit_btn_loc = By.CSS_SELECTOR, "a#submit"
    def add_product(self, product_name, cat_1_text, cat_2_text, cat_3_text, shop_price,
                    market_price, template_text, content_text):
        # 切换frame
        self.switch_frame(self.product_iframe_loc)
        #隐式等待
        self.driver.implicitly_wait(5)
        # 输⼊商品名称
        self.input_text(self.product_name_loc,product_name)
        # 选择商品⼀级、⼆级、三级分类
        self.select_option(self.cat_1_loc,cat_1_text)
        self.select_option(self.cat_2_loc,cat_2_text)
        self.select_option(self.cat_3_loc,cat_3_text)
        # 输⼊本店售价
        self.input_text(self.shop_price_loc,shop_price)
        # 输⼊市场售价
        self.input_text(self.market_price_loc,market_price)
        # 选择运费模版
        self.select_option(self.template_loc,template_text)
        # 切换到编辑框所在到frame
        self.switch_frame(self.ueditor_iframe_Loc)
        # 填写商品详情信息# 返回⽗级frame
        self.input_text(self.content_loc,content_text)
        self.parent_frame()
        # 点击确认
        self.click_el(self.submit_btn_loc)
        # 返回⾸次切⼊的frame的⽗级
        self.parent_frame()

 #普通test实现

import time
from base.base_page import Driver_Tools
from page.htadd_product_page import Add_Page
from page.htindex_page import Index_Page
from page.htlogin_page import Login_Page
from page.htshopping_page import Shop_Page
class Test_AddProduct():
    def setup_class(self):
        self.Iogin_page = Login_Page()
        self.index_page = Index_Page()
        self.shopping_page = Shop_Page()
        self.add_page = Add_Page()
        self.Iogin_page.open_index()
        self.Iogin_page.Iogin_data("admin", "123456", "8888")
        # # 点击商城
        print(self.index_page.get_text())
        self.index_page.go_shop()
        # 点击新增商品页
    def teardown_class(self):
        Driver_Tools.quit()
    def setup(self):
        # 进新增商品页
        self.shopping_page.add_shop_page()
    def test_addshop(self):
        # print(self.shopping_page.get_shop_msg())
        # 新增商品
        self.add_page.add_product("沐浴露awr3005", "个人化妆", "身体护肤", "沐浴",89, 129, "以件计算", "霸王沐浴露,最好的沐浴露~!")
        time.sleep(5)
    # 调用封装弹出框文本
        text =self.shopping_page.get_shop_msg()
        print(text)  # 打印弹出框文本
        assert '沐浴露awr3005' in text#断言实际结果的文本包含预期结果

#上述为前提添加
#1data文件夹中#add_goods.json文件

[
  {
    "desc": "以件计算发布商品成功",
    "product_name": "欧莱雅7组00114",
    "shop_price": "89",
    "market_price": "129",
    "goods_content": "欧莱雅2022新款石榴沐浴露0044",
    "cat_1": "个人化妆",
    "cat_2": "面部护肤",
    "cat_3": "清洁",
    "template": "以件计算"
  },
  {
    "desc": "以体积计算发布商品成功",
    "product_name": "欧莱雅7组00113",
    "shop_price": "89",
    "market_price": "129",
    "goods_content": "欧莱雅2022新款石榴沐浴露0055",
    "cat_1": "个人化妆",
    "cat_2": "面部护肤",
    "cat_3": "清洁",
    "template": "以体积计算"
  }
]

#2#config.py绝对路径

import  os
D=os.path.dirname(__file__)
# D自定义根目录config.py

 #3base文件夹中#read_file.py读取json

import json#导包json
from config import D#导包绝对路径D
#定义读取json的方法定义filename形参用于调用传参
def Read_Data(filename):
    with open(filename, encoding='utf-8') as file:
        data_list = json.load(file) # json默认r读取文件
        # json.load读取加载的数据赋值给变量名data_list
        new_list = []#创建空列表
        for my_dict in data_list:#for循环遍历列表得到字典
            # 字典.values()得到键值并转元组
            my_tuple = tuple(my_dict.values())
            new_list.append(my_tuple)#将得到数据的元组添加给新空列表
        return new_list#返回得到数据的列表值

#4#scripts文件夹中#test_paramadd.py参数化

import time
import pytest
from base.base_page import Driver_Tools
from base.read_file import Read_Data
from config import D
from page.htadd_product_page import Add_Page
from page.htindex_page import Index_Page
from page.htlogin_page import Login_Page
from page.htshopping_page import Shop_Page
class Test_AddProduct():
    def setup_class(self):
        # 创建⻚⾯对象
        self.Iogin_page = Login_Page()
        self.index_page = Index_Page()
        self.shopping_page = Shop_Page()
        self.add_page = Add_Page()
        # 登录后台
        self.Iogin_page.open_index()
        self.Iogin_page.Iogin_data("admin", "123456", "8888")
        # # 点击商城# 进⼊商城⻚⾯
        self.index_page.go_shop()
        # 点击新增商品页
    def teardown_class(self):
        Driver_Tools.quit()
    def setup(self):
        # 进新增商品页
        self.shopping_page.add_shop_page()
        #读取json数据
    read_json=Read_Data(D + '/data/add_goods.json')
    @pytest.mark.parametrize('desc,product_name,shop_price,market_price,goods_content,'
                             'cat_1,cat_2,cat_3,template',read_json)
    #编写测试用例并按需求顺序传参
    def test_addshop(self,desc,product_name,cat_1,cat_2,cat_3,shop_price,market_price,template,goods_content):
        # 新增商品填写信息
        self.add_page.add_product(product_name,cat_1,cat_2,cat_3,shop_price,market_price,template,goods_content)
        time.sleep(5)
    # 添加商品成功后文本
        text =self.shopping_page.get_shop_msg()
        print(desc,text)
        assert product_name in text#断言实际结果的文本包含预期结果

#5#base文件夹中#logging_use.py日志

import logging.handlers
import logging
from config import D
def init_log_config(filename, when='midnight', interval=1, backup_count=7):
    # 1. 创建日志器对象
    logger = logging.getLogger()
    # 2. 设置日志打印级别
    logger.setLevel(logging.INFO)
    # 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)

 #6#scripts文件夹中#test_logadd.py参数化日志

import logging
import time
import pytest
from base.base_page import Driver_Tools
from base.logging_use import init_log_config
from base.read_file import Read_Data
from config import D
from page.htadd_product_page import Add_Page
from page.htindex_page import Index_Page
from page.htlogin_page import Login_Page
from page.htshopping_page import Shop_Page
class Test_AddProduct():
    def setup_class(self):
        # 创建⻚⾯对象
        self.Iogin_page = Login_Page()
        self.index_page = Index_Page()
        self.shopping_page = Shop_Page()
        self.add_page = Add_Page()
        # 登录后台
        self.Iogin_page.open_index()
        self.Iogin_page.Iogin_data("admin", "123456", "8888")
        # # 点击商城# 进⼊商城⻚⾯
        self.index_page.go_shop()
        # 点击新增商品页
    def teardown_class(self):
        Driver_Tools.quit()
    def setup(self):
        # 进新增商品页
        self.shopping_page.add_shop_page()
        #读取json数据
    read_json=Read_Data(D + '/data/add_goods.json')
    @pytest.mark.parametrize('desc,product_name,shop_price,market_price,goods_content,'
                             'cat_1,cat_2,cat_3,template',read_json)
    #编写测试用例并按需求顺序传参
    def test_addshop(self,desc,product_name,cat_1,cat_2,cat_3,shop_price,market_price,template,goods_content):
        # 新增商品填写信息
        self.add_page.add_product(product_name,cat_1,cat_2,cat_3,shop_price,market_price,template,goods_content)
        time.sleep(5)
        # 日志生成路径
        init_log_config(D + '/log/addshop')  # 日志存储路径和生成的文件名
        #日志文件内容
        logging.info(f"desc={desc}, product_name={product_name},shop_price={shop_price},"
                     f""f"market_price={market_price}, goods_content={goods_content}, cat_1={cat_1}, cat_2={cat_2},"
                     f"cat_3={cat_3}, template={template}")
    # 添加商品成功后文本
        text =self.shopping_page.get_shop_msg()
        print(desc,text)
        assert product_name in text#断言实际结果的文本包含预期结果

#7##pytest.ini参数化日志pytest

[pytest]
addopts=-s --html=report/test01_report.html
testpaths=./scripts
python_files=test_logadd.py
python_classes=Test*
python_functions=test*

你可能感兴趣的:(python,UI自动化,python,自动化,selenium)