Pytest-PO模式

1. V1版本

一个用例一个脚本,维护不方便

2.V2版本

通过pytest执行
在这里插入图片描述

配置文件
pytest.ini
addopts = -s -v --html=report/report.html --reruns 1 生成测试报告 用例失败执行一次

[pytest]
addopts = -s -v --html=report/report.html --reruns 1
testpaths = ./V3/./scripts
python_files = test_*.py
python_classes = Test*
python_functions = test_*
V1.原始
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestAdd:

    # 账号不存在
    def test_01(self):
        driver = webdriver.Chrome()
        driver.maximize_window()
        driver.implicitly_wait(10)
        driver.get("http://tpshop-test.itheima.net")
        # 点击登录
        driver.find_element(By.CSS_SELECTOR, ".red").click()
        # 输入不正确的手机号,密码,验证码,点击登录
        driver.find_element(By.NAME, "username").send_keys("13987362332")
        driver.find_element(By.NAME, "password").send_keys("123456")
        driver.find_element(By.NAME, "verify_code").send_keys("8888")
        driver.find_element(By.NAME, "sbtbutton").click()
        # 获取提示信息 因为是要经过后台校验的 所以要等一下
        time.sleep(1)
        msg = driver.find_element(By.CSS_SELECTOR, ".layui-layer-content").text
        # 断言
        assert "账号不存在" in msg
        driver.quit()

    # 密码错误
    def test_02(self):
        driver = webdriver.Chrome()
        driver.maximize_window()
        driver.implicitly_wait(10)
        driver.get("http://tpshop-test.itheima.net")
        # 点击登录
        driver.find_element(By.CSS_SELECTOR, ".red").click()
        # 输入不正确的手机号,密码,验证码,点击登录
        driver.find_element(By.NAME, "username").send_keys("13012345678")
        driver.find_element(By.NAME, "password").send_keys("123")
        driver.find_element(By.NAME, "verify_code").send_keys("8888")
        driver.find_element(By.NAME, "sbtbutton").click()
        # 获取提示信息 因为是要经过后台校验的 所以要等一下
        time.sleep(1)
        msg = driver.find_element(By.CSS_SELECTOR, ".layui-layer-content").text
        # 断言
        assert "密码错误" in msg
        driver.quit()
V2.将重复方法简单提取一下(存在问题;代码冗余)
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestAdd:

    def setup_class(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)
        self.driver.get("http://tpshop-test.itheima.net")
        # 点击登录
        self.driver.find_element(By.CSS_SELECTOR, ".red").click()

    # 账号不存在
    def test_01(self):
        # 输入不正确的手机号,密码,验证码,点击登录
        self.driver.find_element(By.NAME, "username").send_keys("13987362332")
        self.driver.find_element(By.NAME, "password").send_keys("123456")
        self.driver.find_element(By.NAME, "verify_code").send_keys("8888")
        self.driver.find_element(By.NAME, "sbtbutton").click()
        # 获取提示信息 因为是要经过后台校验的 所以要等一下
        time.sleep(1)
        msg = self.driver.find_element(By.CSS_SELECTOR, ".layui-layer-content").text
        print(msg)
        # 断言
        assert "账号不存在" in msg

    # 创建方法级别的fixture,用来刷新页面,清空之前填的数据
    def setup(self):
        self.driver.refresh()

    # 密码错误
    def test_02(self):
        # 输入不正确的手机号,密码,验证码,点击登录
        self.driver.find_element(By.NAME, "username").send_keys("13012345678")
        self.driver.find_element(By.NAME, "password").send_keys("123")
        self.driver.find_element(By.NAME, "verify_code").send_keys("8888")
        self.driver.find_element(By.NAME, "sbtbutton").click()
        # 获取提示信息 因为是要经过后台校验的 所以要等一下
        time.sleep(1)
        msg = self.driver.find_element(By.CSS_SELECTOR, ".layui-layer-content").text
        # 断言
        assert "密码错误" in msg

    def teardown_class(self):
        self.driver.quit()
V3.将重复方法提取成出来,方法封装(存在问题:维护麻烦,没有参数化,如果页面元素发生变化维护起来麻烦)

在这里插入图片描述
注意:要建立一个conftest.py的空文件,要不然会说V3.utils找不到
utils工具类:

import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class UtilsDriver:
    _driver = None #给一个默认值,防止打开一堆浏览器
    # 定义一个获取浏览器驱动的方法
    @classmethod # 表示这是一个类级别的方法,可以通过类名直接调用
    def get_driver(cls):
        if cls._driver is None:
            cls._driver = webdriver.Chrome()
            cls._driver.maximize_window()
            cls._driver.implicitly_wait(10)
        return cls._driver

    # 定义一个退出浏览器驱动的方法
    @classmethod
    def quit_driver(cls):
        # 是None的时候才会退出
        if cls._driver is not None:
            cls.get_driver().quit()
            cls._driver = None

# 获取提示信息的方法
def get_msg():
    time.sleep(1)
    return UtilsDriver.get_driver().find_element(By.CSS_SELECTOR, ".layui-layer-content").text

代码:

from selenium.webdriver.common.by import By

from V3.utils import UtilsDriver, get_msg


class TestLogin:

    def setup_class(self):
        self.driver = UtilsDriver.get_driver()
        # self.driver = webdriver.Chrome()
        # self.driver.maximize_window()
        # self.driver.implicitly_wait(10)
        self.driver.get("http://tpshop-test.itheima.net")
        # 点击登录
        self.driver.find_element(By.CSS_SELECTOR, ".red").click()

    # 账号不存在
    def test_01(self):
        # 输入不正确的手机号,密码,验证码,点击登录
        self.driver.find_element(By.NAME, "username").send_keys("13987362332")
        self.driver.find_element(By.NAME, "password").send_keys("123456")
        self.driver.find_element(By.NAME, "verify_code").send_keys("8888")
        self.driver.find_element(By.NAME, "sbtbutton").click()
        msg = get_msg()
        # 断言
        assert "账号不存在" in msg

    # 创建方法级别的fixture,用来刷新页面,清空之前填的数据
    def setup(self):
        self.driver.refresh()

    # 密码错误
    def test_02(self):
        # 输入不正确的手机号,密码,验证码,点击登录
        self.driver.find_element(By.NAME, "username").send_keys("13012345678")
        self.driver.find_element(By.NAME, "password").send_keys("123")
        self.driver.find_element(By.NAME, "verify_code").send_keys("8888")
        self.driver.find_element(By.NAME, "sbtbutton").click()
        msg = get_msg()
        # 断言
        assert "密码错误" in msg

    def teardown_class(self):
        UtilsDriver.quit_driver()
V4.Po模式

把一个页面分为三层:对象库(封装定位元素方法),操作层(封装元素的操作),业务层(将一个或者多个业务组合起来)

  • 首先要知道用到哪些页面,页面里面用到哪些元素
    在这里插入图片描述

pagehome.py

# 表示首页

from selenium.webdriver.common.by import By

from V4.utils import UtilsDriver


# 对象库层:主要用来定位元素
class PageHome:
    def __init__(self):
        # 浏览器驱动对象
        self.driver = UtilsDriver.get_driver()
        self.login_btn = By.CSS_SELECTOR, ".red"

    # 找到登陆按钮
    def find_login_btn(self):
        return self.driver.find_element(self.login_btn[0], self.login_btn[1])


# 操作层:里面的元素从对象库层来拿
class HandleHome:
    def __init__(self):
        self.home_page = PageHome()

    # 点击登录按钮  挑战到登陆页
    def click_btn_login(self):
        self.home_page.find_login_btn().click()


# 业务层:调用操作层的东西
class HomeProxy:
    def __init__(self):
        self.home_proxy = HandleHome()

    # 跳转到登陆页
    def go_login_page(self):
        self.home_proxy.click_btn_login()

pagelogin.py

# 表示登陆页
from selenium.webdriver.common.by import By

from V4.utils import UtilsDriver


# 对象库层:主要用来定位元素
class PageLogin:
    def __init__(self):
        # 浏览器驱动对象
        self.driver = UtilsDriver.get_driver()
        self.account_btn = By.NAME, "username"
        self.pwd_btn = By.NAME, "password"
        self.keys_btn = By.NAME, "verify_code"
        self.input_btn = By.NAME, "sbtbutton"

    # 找到账户按钮
    def find_account_btn(self):
        return self.driver.find_element(self.account_btn[0], self.account_btn[1])

    # 找到密码按钮
    def find_pwd_btn(self):
        return self.driver.find_element(self.pwd_btn[0], self.pwd_btn[1])

    # 找到验证码按钮
    def find_keys_btn(self):
        return self.driver.find_element(*self.keys_btn)   # 很多参数的时候用*代替就行

    # 找到确定按钮
    def find_input_btn(self):
        return self.driver.find_element(*self.input_btn)  # 很多参数的时候用*代替就行


# 操作层:里面的元素从对象库层来拿
class HandleLogin:
    def __init__(self):
        self.login_page = PageLogin()

    # 输入用户名 密码 验证码 点击登录  输入之前避免有其他文字先进行清空操作
    def input_account(self, username):
        self.login_page.find_account_btn().clear()
        self.login_page.find_account_btn().send_keys(username)

    def input_pwd(self, pwd):
        self.login_page.find_pwd_btn().clear()
        self.login_page.find_pwd_btn().send_keys(pwd)

    def input_keys(self, keys):
        self.login_page.find_keys_btn().clear()
        self.login_page.find_keys_btn().send_keys(keys)

    def input_click(self):
        self.login_page.find_input_btn().click()

# 业务层:调用操作层的东西
class LoginProxy:
    def __init__(self):
        self.login_proxy = HandleLogin()

    # 执行操作层的 输入用户名 密码 验证码 点击登录 四个动作
    def login(self, username, pwd, keys):
        self.login_proxy.input_account(username)
        self.login_proxy.input_pwd(pwd)
        self.login_proxy.input_keys(keys)
        self.login_proxy.input_click()
V5.Po模式优化

在这里插入图片描述
优化显示等待和清除操作
base_page.py


from selenium.webdriver.support.wait import WebDriverWait

from V4.utils import UtilsDriver

# 对象库层的基类
class BasePage:
    def __init__(self):
        # 浏览器驱动对象
        self.driver = UtilsDriver.get_driver()

    # 定义获取元素对象方法  10和1是轮巡   显示等待
    def get_element(self, location):
        wait = WebDriverWait(self.driver, 10, 1)
        element = wait.until(lambda x: x.find_element(*location))
        return element

# 操作层的基类
class BaseHandler:
    # 针对元素操作方法   元素对象  输入内容
    def input_text(self, element, text):
        element.clear()
        element.send_keys(text)

page_home.py

# 表示首页

from selenium.webdriver.common.by import By

from V4.base.base_page import BasePage, BaseHandler
from V4.utils import UtilsDriver


# 对象库层:主要用来定位元素
# 继承基类里面的方法
class PageHome(BasePage):
    def __init__(self):
        # 浏览器驱动对象
        #self.driver = UtilsDriver.get_driver() 继承了基类所以这行不需要了
        super().__init__()  # 因为基类里面也有init,所以super重写一下这个方法
        self.login_btn = By.CSS_SELECTOR, ".red"

    # 找到登陆按钮
    def find_login_btn(self):
        return self.get_element(self.login_btn)
        # return self.driver.find_element(self.login_btn[0], self.login_btn[1])


# 操作层:里面的元素从对象库层来拿
# 继承基类里面的方法
class HandleHome(BaseHandler):
    def __init__(self):
        self.home_page = PageHome()

    # 点击登录按钮  挑战到登陆页
    def click_btn_login(self):
        self.home_page.find_login_btn().click()


# 业务层:调用操作层的东西
class HomeProxy:
    def __init__(self):
        self.home_proxy = HandleHome()

    # 跳转到登陆页
    def go_login_page(self):
        self.home_proxy.click_btn_login()

page_login.py

# 表示登陆页
from selenium.webdriver.common.by import By

from V4.base.base_page import BaseHandler, BasePage
from V4.utils import UtilsDriver


# 对象库层:主要用来定位元素
# 继承基类里面的方法
class PageLogin(BasePage):
    def __init__(self):
        # 浏览器驱动对象
        # self.driver = UtilsDriver.get_driver()
        super().__init__()
        self.account_btn = By.NAME, "username"
        self.pwd_btn = By.NAME, "password"
        self.keys_btn = By.NAME, "verify_code"
        self.input_btn = By.NAME, "sbtbutton"

    # 找到账户按钮
    def find_account_btn(self):
        return self.get_element(self.account_btn)
        # return self.driver.find_element(self.account_btn[0], self.account_btn[1])

    # 找到密码按钮
    def find_pwd_btn(self):
        return self.get_element(self.pwd_btn)
        # return self.driver.find_element(self.pwd_btn[0], self.pwd_btn[1])

    # 找到验证码按钮
    def find_keys_btn(self):
        return self.get_element(self.keys_btn)
        # return self.driver.find_element(*self.keys_btn)   # 很多参数的时候用*代替就行

    # 找到确定按钮
    def find_input_btn(self):
        return self.get_element(self.input_btn)
        # return self.driver.find_element(*self.input_btn)  # 很多参数的时候用*代替就行


# 操作层:里面的元素从对象库层来拿
# 继承基类里面的方法
class HandleLogin(BaseHandler):
    def __init__(self):
        self.login_page = PageLogin()

    # 输入用户名 密码 验证码 点击登录  输入之前避免有其他文字先进行清空操作
    def input_account(self, username):
        self.input_text(self.login_page.find_account_btn(), username)
        # self.login_page.find_account_btn().clear()
        # self.login_page.find_account_btn().send_keys(username)

    def input_pwd(self, pwd):
        self.input_text(self.login_page.find_pwd_btn(), pwd)
        # self.login_page.find_pwd_btn().clear()
        # self.login_page.find_pwd_btn().send_keys(pwd)

    def input_keys(self, keys):
        self.input_text(self.login_page.find_keys_btn(), keys)
        # self.login_page.find_keys_btn().clear()
        # self.login_page.find_keys_btn().send_keys(keys)

    def input_click(self):
        self.login_page.find_input_btn().click()

# 业务层:调用操作层的东西
class LoginProxy:
    def __init__(self):
        self.login_proxy = HandleLogin()

    # 执行操作层的 输入用户名 密码 验证码 点击登录 四个动作
    def login(self, username, pwd, keys):
        self.login_proxy.input_account(username)
        self.login_proxy.input_pwd(pwd)
        self.login_proxy.input_keys(keys)
        self.login_proxy.input_click()

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值