关键字驱动+excel数据驱动

conf文件

chrome_options.py

'''
    options类或者是函数的形态,专门用于管理options相关设置。一定记得在末尾要使用return来返回。
'''
from selenium import webdriver


def options():
    # 创建一个options对象,进行浏览器的设置项定义。什么    options = webdriver.ChromeOptions()浏览器就创建对应的options对象即可
    options = webdriver.ChromeOptions()
    # 页面加载策略
    # options.page_load_strategy = 'normal'

    # 想要添加设置项的时候,常用的两个添加设置方法
    # options.add_experimental_option()  # 添加试验性质的参数,意味着可能存在不稳定的情况,但是实际上没有发现有什么不稳定。
    # options.add_argument()  # 添加常规参数

    # 窗体最大化
    options.add_argument('start-maximized')
    # 窗体的指定坐标启动:该方法只能针对未最大化窗体的浏览器进行设置。
    # options.add_argument('window-position=300,600')
    # 窗体的初始化尺寸定义
    # options.add_argument('window-size=1000,1200')

    # 自动化测试黄条警告去除
    options.add_experimental_option('excludeSwitches', ['enable-automation', 'enable-logging'])
    # options.add_experimental_option('disable-infobars') # 只有python27的版本才有效,现在看到可以直接忽略。

    # 无头模式:浏览器不以界面形态来运行。但是实际上,该执行的相关操作依旧还是会正常执行。这种模式可以降低GPU和CPU资源的耗费。无头模式在特定的场景下可能会出现BUG
    # options.add_argument('--headless')

    # 账号密码保存弹窗的去除
    prefs = {
        'credentials_enable_service': False,
        'profile.password_manager_enable': False
    }
    options.add_experimental_option('prefs', prefs)

    # 加载用户本地缓存信息
    '''
        selenium默认启动的浏览器,是不会加载本地缓存信息的。也就意味着Selenium启动的浏览器是完全全新且独立的浏览器,不会与本地的数据进行任何的交互
            1. 全新浏览器访问系统时会有验证码的风险。
            2. 验证码本身是用于防止自动化脚本恶意访问的,所以Selenium不处理验证码
        如果想要避免验证码的风险,其中一种手段就是加载本地缓存信息。
        想要绕过登录,加载本地缓存是一个最直接的方法,但是前提是网站本身具备有保存登录状态的功能。
        要通过Selenium调用本地缓存,一定要提前将浏览器全部关闭,再启动自动化脚本,否则会报错。
    '''
    # options.add_argument(r'--user-data-dir=C:\Users\15414\AppData\Local\Google\Chrome\User Data')

    # 启动隐身模式
    # options.add_argument('incognito')

    # 去除控制台的多余信息:首选此方法
    # options.add_experimental_option('excludeSwitches', ['enable-logging'])
    # 进一步去除系统多余信息,去除多余日志的第二道保险
    options.add_argument('--log_level=3')
    options.add_argument('--disable-gpu')
    options.add_argument('--ignore-certificate-errors')

    # 对options设置好以后一定要记得用return返回。
    return options

log_conf.ini

[loggers]
keys = root

[handlers]
keys = fileHandler,streamHandler

[formatters]
keys = simpleFormatter

[logger_root]
level = DEBUG
handlers = fileHandler,streamHandler

[handler_fileHandler]
class = FileHandler
level = DEBUG
formatter = simpleFormatter
args = ('log_conf.log','a','utf-8')

[handler_streamHandler]
class = StreamHandler
level = DEBUG
formatter = simpleFormatter

[formatter_simpleFormatter]
format = %(levelname)s %(asctime)s %(filename)s %(module)s %(funcName)s %(lineno)s : %(message)s

logging_conf.py

'''
    读取ini配置文件中的logging,实现日志的输出和记录
        要读取配置文件,需要通过logging.config来实现
    配置ini文件的相对绝对路径,就是根据工程路径来获取它的绝对路径。
        基于pathLib库来实现文件路径的获取
'''
import logging.config
import pathlib


# 封装日志记录器的函数
def getLogger():
    # 读取配置文件
    # logging.config.fileConfig(path, encoding='utf-8')
    # 获取当前文件所在的路径
    file_path = pathlib.Path(__file__)
    # 获取当前文件的上一级
    dir = file_path.parents[0].resolve()  # 返回路径对象
    # 基于上一级获取到log_conf.ini文件
    file = dir / 'log_conf.ini'

    logging.config.fileConfig(file, encoding='utf-8')
    # 获取记录器
    logger = logging.getLogger()
    return logger  # 一定记得要return,不然无法获取logger对象,来实现日志的输出记录


# 获取记录器
# logger = getLogger()
# logger.debug('这是配置文件的debug')
# logger.info('这是配置文件的info')
# logger.error('这是配置文件的error')
# file_path = pathlib.Path(__file__)
# print(file_path)
# dir = file_path.parents[0].resolve()  # 返回路径对象
# print(dir)
# print(type(dir))
# file = dir / 'log_conf.ini'
# print(file)

excel_driver文件

excel_driver.py

'''
    Excel数据驱动关联关键字驱动实现自动化测试流程
'''
import openpyxl

from excel_driver.excel_style import pass_, failed
from web_keys.web import WebKeys

# log = getLogger()

# 定义数据初始化
success = 0
fail = 0
fail_list = []


# 参数解析函数
def argument(value):
    # 参数解析处理,将str的xxx=xxx的格式转换为字典的形态,然后通过**的方式传入到对应的操作方法之中
    da = dict()
    if value:  # 因为value可能为none,所以要提前判断一下
        str_temp = value.split(';')  # 可能参数有多个,基于;进行分割,所以提前分割好参数的数量
        for temp in str_temp:
            # temp: by=id    value=kw     txt=xxxxx
            t = temp.split('=', 1)  # 基于=进行1次分割操作
            da[t[0]] = t[1]  # 将分割后的t的两个元素,作为key和value,进行保存
            # data["type_"] = "Chrome"  # 对字典中的指定key进行value的赋值,于是data={"type_":"Chrome"}
    return da


def run(log, file):
    global success, fail
    # 实现Excel文件的内容读取
    excel = openpyxl.load_workbook(file)
    # sheet = excel['Sheet1']
    sheets = excel.sheetnames  # 获取所有的sheet页的名字
    log.info(f'****************开始执行{file}测试用例********************')
    for name in sheets:  # 基于不同sheet页的名字,进行不同sheet页内容的获取
        sheet = excel[name]
        log.info(f'进入到{name}的sheet页,进行测试操作')
        # 用例内容的处理
        for values in sheet.values:
            # 只要第一个单元格是int类型,则输出
            if type(values[0]) is int:
                # print(values)
                # 参数:每一个操作行为对应的参数内容,将所有的参数转为字典格式,以便于后续的**方式的传参
                data = argument(values[2])
                # 描述:用于当前执行步骤的日志信息
                log.info("正在执行操作行为:" + values[3])
                # 操作行为:每一行用例的最终执行行为
                # 实例化浏览器对象
                if values[1] == 'open_browser':
                    wk = WebKeys(log=log, **data)  # 实例化wk对象
                # 因为断言会有返回值,需要结合返回值来执行相关对应的操作,所以断言作为独有的一个判断机制。
                elif 'assert' in values[1]:
                    status = getattr(wk, values[1])(expected=values[4], **data)  # 只要是断言都会有返回值
                    if status:
                        # 单元格写入pass
                        pass_(sheet.cell(row=values[0] + 2, column=6))
                        success += 1
                    else:
                        # 单元格写入failed
                        failed(sheet.cell(row=values[0] + 2, column=6))
                        fail += 1
                        fail_list.append(f'失败用例为{file}文件中的{name}Sheet页')
                    # 因为有断言的写入,所以需要进行文件的保存
                    excel.save(file)
                # 基于实例化浏览器对象进行的常规操作行为
                else:
                    status = getattr(wk, values[1])(**data)  # 基于反射机制,满足所有的操作行为

    excel.close()
    log.info('测试执行完毕,正在退出中。。。。。。')
    # log.warning(f'''
    #     用例执行总数:{success + fail}
    #     成功用例为:{success}个,
    #     失败用例为:{fail}个,失败用例集:{fail_list}
    # ''')


# 数据的结果输出
def sum_info(log):
    log.warning(f'''
            用例执行总数:{success + fail}
            成功用例为:{success}个,
            失败用例为:{fail}个,失败用例集:{fail_list}
        ''')

excel_style.py

'''
    单元格写入的样式封装
'''
from openpyxl.styles import PatternFill, Font


# PASS配置
def pass_(cell):
    # 设置pass值.
    cell.value = 'PASS'
    # 定义单元格的颜色和样式:绿色底,字体加粗
    cell.fill = PatternFill('solid', fgColor='AACF91')  # 单元格填充绿色底
    cell.font = Font(bold=True)  # 加粗


# FAILED配置
def failed(cell):
    # 设置failed值.
    cell.value = 'FAILED'
    # 定义单元格的颜色和样式:红色底,字体加粗
    cell.fill = PatternFill('solid', fgColor='FF0000')  # 单元格填充红色底
    cell.font = Font(bold=True)  # 加粗

test_data文件

web_keys文件

web.py

'''
    关键字驱动类,属于逻辑代码类。
        只是基本业务逻辑的封装,本身不参与到任何实际的测试行为之中,单独运行不会有任何的意义。只有在被调用了之后才会产生作用。
    关键字驱动类的逻辑代码实现:
        关键字驱动又叫做Selenium的二次封装。其实体现的就是面向对象编程思维逻辑。
        Selenium本身具备有非常多的方法,来提供给到自动化测试。关键字驱动就是将Selenium中常用的操作行为进行提取。封装成各种对应的关键字。
        从而实现在后续的实际测试过程中,通过调用中这些关键字,来解决实际的自动化测试需要。
        常用的操作行为:
            1. 访问url
            2. 定位元素
            3. 输入
            4. 点击
            。。。。。
    关键字驱动类,常规而言都是基于操作行为来提取和封装,同时也可以基于业务流程来进行封装,也可以考虑做公共流程的关键字封装。
    不同企业的测试需求不同,所以自动化测试框架在实现的时候也会有不同。一定不要认为一套固定的测试框架可以解决所有企业的需求。

    关键字驱动类,一般来说,是不会单独进行使用的。在平时测试过程中,都是会结合到其他的模块一同使用。最最起码的是会关联到数据驱动。
    本身就是一种基本的行为封装类。没有什么很特别的东西。也不会存在很难的所谓的难点知识。
        1. 关联到数据驱动和测试用例来一同使用
        2. 结合企业的实际需要,进行定制化框架研发。
    所有的所谓高级的技术,其实就是多个基础知识叠加在一起,最终就变成了高级技术。真正的难,在于设计思维的培养。
    代码一定没有十全十美的。也不可能一次性把所有的关键字都封装好。如果遇到实际业务需要特定的操作行为,我们再去封装到关键字之中即可。
'''
import traceback
from time import sleep

from selenium import webdriver

from conf.chrome_options import options
from conf.logging_config import getLogger

# log = getLogger()


# driver对象生成
def open_browser(type_):
    if type_.capitalize() == 'Chrome':
        driver = webdriver.Chrome(options=options())
    else:
        try:
            driver = getattr(webdriver, type_.capitalize())()
        except:
            driver = webdriver.Chrome()
    return driver


class WebKeys:
    # 定义临时driver对象
    # driver = webdriver.Chrome()

    # 构造方法
    def __init__(self, type_, log):
        self.driver = open_browser(type_)
        self.driver.implicitly_wait(5)
        self.log = log

    # 访问url
    def open(self, url):
        self.driver.get(url)

    # 定位元素
    def locator(self, by, value):
        return self.driver.find_element(by, value)

    # 输入
    def input(self, by, value, txt):
        # self.driver.find_element().send_keys()
        el = self.locator(by, value)
        el.clear()
        el.send_keys(txt)

    # 点击
    def click(self, by, value):
        self.locator(by, value).click()

    # 关闭
    def quit(self):
        self.driver.quit()

    # 强制等待
    def wait(self, time_):
        sleep(int(time_))

    # 文本断言
    def assert_in(self, expected, by, value):
        try:
            reality = self.locator(by, value).text
            assert expected in reality, f'''
                断言失败:
                    expected:{expected}
                    reality:{reality}
                    expected != reality
            '''
            return True
        except:
            self.log.error(traceback.format_exc())
            return False

log_conf.log

ERROR 2023-10-15 21:36:12,065 main.py main <module> 29 : 这不是测试用例.txt文件不是测试用例,本次不执行
WARNING 2023-10-15 21:36:12,066 excel_driver.py excel_driver sum_info 83 : 
            用例执行总数:0
            成功用例为:0个,
            失败用例为:0个,失败用例集:[]
        
INFO 2023-10-15 21:36:12,070 excel_driver.py excel_driver run 37 : ****************开始执行./test_data/test_fecmall.xlsx测试用例********************
INFO 2023-10-15 21:36:12,071 excel_driver.py excel_driver run 40 : 进入到Sheet1的sheet页,进行测试操作
INFO 2023-10-15 21:36:12,071 excel_driver.py excel_driver run 49 : 正在执行操作行为:创建一个chrome浏览器
INFO 2023-10-15 21:36:12,074 excel_driver.py excel_driver run 37 : ****************开始执行./test_data/test_demo.xlsx测试用例********************
INFO 2023-10-15 21:36:12,074 excel_driver.py excel_driver run 40 : 进入到Sheet1的sheet页,进行测试操作
INFO 2023-10-15 21:36:12,075 excel_driver.py excel_driver run 49 : 正在执行操作行为:创建一个chrome浏览器
INFO 2023-10-15 21:36:13,268 excel_driver.py excel_driver run 49 : 正在执行操作行为:访问Fecmall的登录页
INFO 2023-10-15 21:36:13,318 excel_driver.py excel_driver run 49 : 正在执行操作行为:访问百度首页
INFO 2023-10-15 21:36:14,679 excel_driver.py excel_driver run 49 : 正在执行操作行为:输入账号:2375154305@qq.com
INFO 2023-10-15 21:36:14,742 excel_driver.py excel_driver run 49 : 正在执行操作行为:输入密码:hcc123456
INFO 2023-10-15 21:36:14,806 excel_driver.py excel_driver run 49 : 正在执行操作行为:点击登录按钮
INFO 2023-10-15 21:36:15,008 excel_driver.py excel_driver run 49 : 正在执行操作行为:断言登录是否成功
INFO 2023-10-15 21:36:15,029 excel_driver.py excel_driver run 49 : 正在执行操作行为:强制等待3秒
INFO 2023-10-15 21:36:15,156 excel_driver.py excel_driver run 49 : 正在执行操作行为:在百度搜索框中输入”黄财财教你Excel数据驱动“
INFO 2023-10-15 21:36:15,562 excel_driver.py excel_driver run 49 : 正在执行操作行为:点击百度一下按钮
INFO 2023-10-15 21:36:15,701 excel_driver.py excel_driver run 49 : 正在执行操作行为:断言校验搜索是否成功,基于搜索工具元素是否出现作为断言的依据
INFO 2023-10-15 21:36:16,171 excel_driver.py excel_driver run 49 : 正在执行操作行为:强制等待3秒
INFO 2023-10-15 21:36:18,044 excel_driver.py excel_driver run 49 : 正在执行操作行为:关闭浏览器,并释放资源
INFO 2023-10-15 21:36:19,174 excel_driver.py excel_driver run 49 : 正在执行操作行为:关闭浏览器,并释放资源
INFO 2023-10-15 21:36:20,120 excel_driver.py excel_driver run 73 : 测试执行完毕,正在退出中。。。。。。
INFO 2023-10-15 21:36:21,287 excel_driver.py excel_driver run 40 : 进入到Sheet3的sheet页,进行测试操作
INFO 2023-10-15 21:36:21,287 excel_driver.py excel_driver run 49 : 正在执行操作行为:创建一个chrome浏览器
INFO 2023-10-15 21:36:26,538 excel_driver.py excel_driver run 49 : 正在执行操作行为:访问百度首页
INFO 2023-10-15 21:36:27,332 excel_driver.py excel_driver run 49 : 正在执行操作行为:在百度搜索框中输入”黄财财教你Excel数据驱动“
INFO 2023-10-15 21:36:27,490 excel_driver.py excel_driver run 49 : 正在执行操作行为:点击百度一下按钮
INFO 2023-10-15 21:36:27,598 excel_driver.py excel_driver run 49 : 正在执行操作行为:断言校验搜索是否成功,基于搜索工具元素是否出现作为断言的依据
ERROR 2023-10-15 21:36:28,032 web.py web assert_in 96 : Traceback (most recent call last):
  File "D:\pyworkspace\web_ui_vip3\web_keys\web.py", line 88, in assert_in
    assert expected in reality, f'''
AssertionError: 
                断言失败:
                    expected:搜索工具1
                    reality:搜索工具
                    expected != reality
            

INFO 2023-10-15 21:36:28,042 excel_driver.py excel_driver run 49 : 正在执行操作行为:强制等待3秒
INFO 2023-10-15 21:36:31,047 excel_driver.py excel_driver run 49 : 正在执行操作行为:关闭浏览器,并释放资源
INFO 2023-10-15 21:36:33,180 excel_driver.py excel_driver run 73 : 测试执行完毕,正在退出中。。。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值