基于关键字驱动的自动化设计

一、conf

1、options.py options函数的封装

'''
    options函数的封装
'''
from selenium import webdriver


# 创建一个options函数
def get_options():
    options = webdriver.ChromeOptions()
    # 页面加载策略
    options.page_load_strategy = 'normal'
    # 窗体最大化:默认启动的浏览器是窗体最大化
    options.add_argument('start-maximized')

    # 指定浏览器的启动坐标:只针对未最大化窗体的浏览器对象
    # options.add_argument('window-position=500,500')

    # 指定浏览器的窗体大小
    # options.add_argument('window-size=1500,1500')

    # 去除浏览器中的自动化测试黄条(警告条):这个东西现在用处不大
    options.add_experimental_option('excludeSwitches', ['enable-automation', 'enable-logging'])
    # options.add_experimental_option('disable-infobars') # 无效,因为是python27的版本才有效。

    # 无头模式:浏览器不以界面化的形态运行。但是实际上该执行的操作还是依旧会正常执行,可以降低GPU和CPU的方式。无头模式依旧会在特殊情况下出现问题,例如Jenkins之中
    # options.add_argument('--headless')  # 有选择性地使用就好。一般在并发测试用例时可以考虑使用。

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

    # 加载本地缓存信息:通过driver对象启动的浏览器默认是不会加载本地缓存的。
    '''
        加载本地缓存信息的时候一定注意,启动代码前要关闭所有当前正在运行的浏览器
            本身缓存文件也是文件的一种,如果有已经启动的浏览器,则该文件就已经处于使用状态,所以再启动浏览器会报错。
        这也是一种绕过登录的操作方式,也就意味着绕过了验证码
    '''
    # 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

2、read_yaml.py yaml文件读取

'''
    yaml文件的读取
'''
import yaml


# 读取yaml文件中的内容,并返回值
def read(file):
    file = open(file, 'r', encoding='utf-8')
    values = yaml.load(stream=file, Loader=yaml.FullLoader)
    return values

# print(read('../test_data/login.yaml'))

二、test_cases 测试用例

1、test_fecmall.py 关键字驱动下的测试用例

'''
    关键字驱动类模式下实现的pytest测试执行:
        1. 基于同一个driver对象来实现,避免在测试过程中出现多个浏览器,导致运行的时间会更加缓慢
        2. 所有的操作内容,都是基于已登录状态来实现的,除去登录本身。
        3. 针对用例本身执行的内容,需要做Fixture的设计,看哪些内容适合于在Fixture中进行定义
        4. 基于pytest会关联到setup和teardown,要合理化设计对应的内容
        5. 业务层级的Fixture可以再考虑再设计,但是一定要结合整体业务逻辑去进行思考。
        6. 对于pytest本身,是否需要定义pytest.ini和conftest.py来解决测试过程中有可能会需要解决的问题。
    测试用例的内容,还是尽可能详细进行编写。毕竟只是写一次的东西
'''
import os
from time import sleep

import allure
import pytest

from class30_pytest_auto.conf.read_yaml import read


# 商城的登录操作

# def test_login(driver, login):
#     sleep(2)
#     driver.open('http://www.baidu.com')
@allure.epic('实现fecmall商品的下单流程')
@allure.feature('商品下单功能')
@allure.story('实现商品下单到支付页面的流程')
@allure.title('商品下单与支付')
@allure.step('下单与支付')
@pytest.mark.parametrize('login', read('../test_data/login.yaml'), indirect=True)
@pytest.mark.parametrize('data', read('../test_data/order.yaml'))
# 添加商品订单
def test_order(driver, login, data):
    '''
        该用例用于实现在登录后,对fecmall进行的定点测试商品添加购物车流程
    '''
    try:
        with allure.step('实现测试数据处理'):
            url, data = data['url'], data['data']
        with allure.step('访问商品详情页'):
            driver.open(url)
        with allure.step('输入购买数量'):
            driver.input(**data['num'])
        with allure.step('点击添加购物车按钮'):
            driver.click(**data['button'])
        with allure.step('流程末尾的校验'):
            driver.assert_text(**data['assert'])
        with allure.step('运行流程末尾的截图'):
            1 / 0
            allure.attach(driver.get_screenshot_as_png(), '最终结尾', allure.attachment_type.PNG)
        # with allure.step('运行后的等待'):
        #     sleep(5)
    except:
        with allure.step('运行失败,进行截图'):
            allure.attach(driver.get_screenshot_as_png(), '失败截图', allure.attachment_type.PNG)
        raise


# 收藏商品
def test_add(driver):
    try:
        # 访问指定的商品详情页
        driver.open(
            'http://hcc.fecmall.com/pair-of-stylish-button-embellished-hollow-out-mesh-shape-knitted-boot-cuffs-for'
            '-women')
        # 点击收藏该产品
        driver.click('partial link text', '收藏该产品')
        driver.wait(5)
        1 / 0
    except:
        with open('../temp/1.png', 'wb') as file:
            file.write(driver.get_screenshot_as_png())
        raise


# 修改个人信息
def test_edit_info():
    pass


if __name__ == '__main__':
    pytest.main(['-sv', './test_fecmall.py', '--alluredir=./report_allure'])
    os.system('allure generate ./report_allure -o ./report --clean')

三、test_data 测试数据

1、login_yaml 登录yaml文件

-
  url: http://hcc.fecmall.com/customer/account/login
  data:
    user:
      by: id
      value: email
      txt: 123@qq.com
    pwd:
      by: id
      value: pass
      txt: 3333
    button:
      by: id
      value: js_registBtn

2、order.yaml 下单yaml文件

-
  url: http://hcc.fecmall.com/off-the-shoulder-long-sleeve-high-low-day-dress-green#product_page_info
  data:
    num:
      by: name
      value: qty
      txt: 10
    button:
      by: id
      value: js_registBtn
    assert:
      by: xpath
      value: //button[@title="Proceed to Checkout"]/span/span
      expected: 继续支付

三、web_keys

1、web_keys.py 关键字驱动类

'''
    关键字驱动类
'''
from time import sleep

from selenium import webdriver

from class17_options.options import get_options


# 基于用户需要,创建对应浏览器对象
def open_browser(type_):
    # if type_ == 'chrome ':
    #     driver = webdriver.Chrome()
    # elif
    if type_ == 'Chrome':
        driver = webdriver.Chrome(options=get_options())
    else:
        try:
            driver = getattr(webdriver, type_)()
        except:
            driver = webdriver.Chrome()
    return driver


# 这只是一种思路。能够解决问题的方式有万千,多去思考。
# def open_browser_plus(type_):
#     '''
#         你无法判断用户会输入什么样的内容,很可能不会遵循你的要求,例如:
#             Chrome:chrome,google chrome,Chrome,gc,谷歌浏览器
#     '''
#     # 定义一个浏览器的完整内容
#     browser = {
#         'Chrome': ['chrome', 'google chrome', 'Chrome', 'gc']
#     }
#     for key, value in browser.items():
#         if type_ in value:
#             driver = getattr(webdriver, key)()
#             break
#     return driver


# 关键字驱动类
class WebKeys:
    # 临时的driver对象
    # driver = webdriver.Chrome()

    # 构造函数
    def __init__(self, type_):
        self.driver = open_browser(type_)
        self.driver.implicitly_wait(5)

    # 访问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):
        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 above(self):
        pass

    # 切换句柄:解决三个方法才能解决的问题。
    def switch_handle_new(self, close=None, num=1):
        handles = self.driver.window_handles
        if close is not None:
            self.driver.close()
        self.driver.switch_to.window(handles[num])

    # 切换句柄
    def switch_handle(self):
        handles = self.driver.window_handles
        self.driver.switch_to.window(handles[1])

    # 切换句柄
    def switch_handle_with_close(self):
        handles = self.driver.window_handles
        self.driver.close()
        self.driver.switch_to.window(handles[1])

    # 切换句柄
    def switch_handle_default(self):
        handles = self.driver.window_handles
        self.driver.switch_to.window(handles[0])

    # 文本断言:in包含文本的形式来断言
    def assert_text_in(self, by, value, expected):
        try:
            reality = self.locator(by, value).text  # 定义实际结果
            message = f'''
            断言失败:
                expected:{expected}
                reality:{reality}
                {expected} != {reality}
            '''
            assert expected in reality, message
            return True
        except:
            return False

    # 文本断言:判断文本是否一致的形式来断言
    def assert_text(self, by, value, expected):
        reality = self.locator(by, value).text  # 定义实际结果
        message = f'''
        断言失败:
            expected:{expected}
            reality:{reality}
            {expected} != {reality}
        '''
        assert expected == reality, message

    # 实现截图
    def get_screenshot_as_png(self):
        return self.driver.get_screenshot_as_png()
    # 登录
    # def login(self):
    #     self.input()    # 账号
    #     self.input()    # 密码
    #     self.click()    # 点击登录按钮

四、根目录下的 conftest.py

1、conftest.py  Fixture编写

'''
    定义在测试过程中会有的Fixture
        1. 如果想生成不同的driver对象,则可以通过调用不同的Fixture即可
        2. 所有操作行为都离不开login的相关行为,所以封装login的Fixture
'''
import pytest

from class30_pytest_auto.web_keys.web_keys import WebKeys


# driver对象的初始化,不同的用例py文件可能会关联不同的测试内容,需要分开管理driver对象
@pytest.fixture(scope='module')
def driver(request):
    # 添加teardown
    def driver_finalizer():
        driver.quit()

    # 注册teardown
    request.addfinalizer(driver_finalizer)
    # driver生成逻辑
    driver = WebKeys('Chrome')
    return driver


# 生成IE浏览器示例
@pytest.fixture(scope='module')
def ie_driver():
    driver = WebKeys('Ie')
    return driver


# 实现login的Fixture定义
@pytest.fixture
def login(driver, request):
    # 基于yaml文件解析获取的参数内容
    url, data = request.param['url'], request.param['data']
    # 访问url
    driver.open(url)
    # 账号输入
    driver.input(**data['user'])
    # 密码输入
    driver.input(**data['pwd'])
    # 确认按钮的点击
    driver.click(**data['button'])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值