web自动化笔记十四:PO模式封装

目录

Po模式封装  

V1模式执行代码

V2执行代码

V3版本 

V4版本


Po模式封装  

    V1-V6
    V1:不采用任何模式(线性模型)
    V2:采用测试框架 unittest
    V3:业务代码和页面对象进行
    V4:实际中的po模式编写
    V5:对PO分层之后的代码继续优化
    V6:把共同操作提取封装到父类中,子类直接调用父类的方法,避免代码冗余

案例:
   百度账号登陆
        1、账号不存在
        2、密码错误

V1模式执行代码

#导包
from selenium import webdriver
from time import sleep
#获取driver对象
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
#最大化浏览器
driver.maximize_window()
#隐式等待
driver.implicitly_wait(30)
#获取url
driver.get("http://www.baidu.com")
"""
账号错误
"""
#定位登陆元素点击
driver.find_element(By.CSS_SELECTOR,"#s-top-loginbtn").click()
#输入用户名
sleep(2)
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__userName").clear()
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__userName").send_keys("1596263494")
#输入密码
sleep(2)
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__password").clear()
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__password").send_keys("234567")
#点击登陆
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__submit").click()
sleep(2)
#获取错误信息
text = driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__error").text
print(text)
"""
手机号码为空
"""
# 清空手机号码
sleep(2)
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__userName").clear()
#输入密码
sleep(2)
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__password").clear()
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__password").send_keys("234567")
#点击登陆
driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__submit").click()
sleep(2)
#获取错误信息
text = driver.find_element(By.CSS_SELECTOR,"#TANGRAM__PSP_11__error").text
print(text)
#退出浏览器
driver.quit()

执行结果:

用户名或密码有误,请重新输入或找回密码
请您输入手机号/用户名/邮箱
 

V2执行代码

# 导包
import time
from selenium import webdriver
import unittest
# 创建测试类
from selenium.webdriver.common.by import By

class TestLogin(unittest.TestCase):
    driver = None
    # 创建单元测试方法
    # 使用fixture装置函数
    @classmethod
    def setUpClass(cls):
        """
        创建driver对象
        最大化浏览器
        设置隐式等待
        :return:
        """
        cls.driver = webdriver.Chrome()
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(30)
        # 获取网页URL
        cls.driver.get("http://www.baidu.com")
        # 定位登陆元素点击
        cls.driver.find_element(By.CSS_SELECTOR, "#s-top-loginbtn").click()
    @classmethod
    def tearDownClass(cls):
        """
        关闭浏览器
        :return:
        """
        cls.driver.quit()


    def testLogin(self):
        """
        密码错误
        :return:
        """
        driver = self.driver

        # 输入用户名
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").clear()
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").send_keys("1596263494")
        # 输入密码
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").clear()
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").send_keys("234567")
        # 点击登陆
        time.sleep(3)
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__submit").click()
        # 获取错误信息
        msg = driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__error").text
        print("msg:", msg)
        # 断言错误信息
        try:
            assert msg == "用户名或密码有误,请重新输入或"
        except AssertionError:
            # 断言错误截图
            driver.get_screenshot_as_file("./image/{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))
    def testLoginNotExist(self):
        """
        账号为空
        :return:
        """
        driver = self.driver
        # 清空用户名
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").clear()
        # 清空密码
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").clear()
        # 输入密码
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").send_keys("234567")
        # 点击登陆
        time.sleep(3)
        driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__submit").click()
        # 获取错误信息
        msg = driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__error").text
        print("msg:", msg)
        try:
            assert msg == "请您输入手机号/用户名/邮箱"
        except AssertionError:
            # 断言错误截图
            driver.get_screenshot_as_file("./image/{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))


执行结果:
msg: 用户名或密码有误,请重新输入或

msg: 请您输入手机号/用户名/邮箱

V3版本 

V1问题:无法批量运行
V2问题:业务脚本与页面对象没有分开
V3问题:代码冗余量太大

PO介绍:
    PO:page(页面)|  object(对象)

页面对象层:
页面对象编写技巧:
    类名:使用大驼峰将模块名称抄进来,有下划线去掉下划线
    方法:根据业务需求每个操作步骤单独封装一个方法
        方法名:page_XXX

组装业务方法:
V3po封装:


    页面层执行代码:

# 导包
from selenium import webdriver
# 创建页面类
from selenium.webdriver.common.by import By


class PageLogin():
# 初始化对象
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)
        self.driver.get("http://www.baidu.com")
    # 点击登陆链接按钮
    def page_login(self):
        self.driver.find_element(By.CSS_SELECTOR, "#s-top-loginbtn").click()
    # 输入用户名
    def page_username(self,username):
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").clear()
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").send_keys(username)
# 输入密码
    def page_password(self,password):
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").clear()
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").send_keys(password)
# 点击登陆按钮
    def page_login_ok(self):
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__submit").click()
# 获取错误信息
    def page_msg_info(self):
        return self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__error").text
    # 封装页面方法
    def pageLoginWays(self,username,password):
        self.page_login()
        self.page_username(username)
        self.page_password(password)
        self.page_login_ok()

业务层执行代码:

import time
import unittest
from parameterized import parameterized
from base_page.page_login import PageLogin
# 创建测试类
class TestLogin(unittest.TestCase):
    # 创建fixture内置函数
    def setUp(cls):
        cls.login = PageLogin()

    def tearDown(cls):
        cls.login.driver.quit()
    # 创建测试方法
    @parameterized.expand([('1596263494','123123',"用户名或密码有误,请重新输入或"),('','123123',"请您输入手机号/用户名/邮箱")])
    def testMsg(self,username,password,msg):
        self.login.pageLoginWays(username,password)
        text = self.login.page_msg_info()
        try:
            self.assertEqual(text,msg)
        except AssertionError:
            self.login.driver.get_screenshot_as_file("../image/{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))

V4版本

 结构:
        1、base(基类):page界面一些公共的方法;
            #Base类:
                初始化方法
                查找元素方法
                点击元素方法
                输入框方法
                获取文本方法
                截图方法
            注意:
                1、以上方法封装的时候,解包只需1次,在查找元素解包
                2、driver为虚拟,谁调用base时,谁传入,无需关注从哪里来;
                3、loc:真正使用loc的方法只有查找元素方法使用
        2、page(页面对象):一个页面封装成一个对象;
            应用:继承base
            实现:
                1、模块名:page+实际操作模块名称  如:page_login.py
                2、页面对象名:以大驼峰方法将模块名抄进来,有下划线去掉下划线
                3、方法:涉及元素,将每个元素操作单独封装一个操作方法
                4、组装:根据需求组装以上操作步骤
        3、scripts/cases(业务层):导包调用page页面,
            实现:
                1、模块:test+实际操作模块名称 如:test.login.py
                2、页面对象名:以大驼峰方法将模块名抄进来,有下划线去掉下划线
                3、方法:
                    1、初始化方法setUp() 注:在unittest框架中不能使用def __init__()初始化方法;
                        #实例化页面对象
                        #前置操作 如打开等等
                    2、结束方法teardown
                        #关闭驱动
                    3、测试方法
                        #根据操作的业务来实现

扩展:
    loc变量:类型为元祖:*loc为解包

代码包结构:

base类代码:

import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait


class Base():
# 初始化driver
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get("https://www.baidu.com")

    # 查找元素方法
    def base_find_element(self,loc,time=30,poll = 1):
        return WebDriverWait(self.driver,timeout=time,poll_frequency=poll).until(lambda x: x.find_element(*loc))
    # 点击方法
    def base_click(self,loc):
        self.base_find_element(loc).click()
    # 输入文本框方法
    def base_send_keys(self,loc,value):
        el = self.base_find_element(loc)
        # 清除元素输入框
        el.clear()
        el.send_keys(value)
    # 获取文本方法
    def base_error_text(self,loc):
        return self.base_find_element(loc).text
    # 截图方法
    def base_screenshot_as_file(self):
        self.driver.get_screenshot_as_file("../image/{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))

page中__init__代码:(做数据)

from selenium.webdriver.common.by import By

login_link = By.CSS_SELECTOR,"#s-top-loginbtn"
login_username = By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName"
login_pwd = By.CSS_SELECTOR, "#TANGRAM__PSP_11__password"
login_btn_ok = By.CSS_SELECTOR, "#TANGRAM__PSP_11__submit"
login_error_text = By.CSS_SELECTOR, "#TANGRAM__PSP_11__error"


pagelogin中代码:

import time
import page
from base.base import Base

class PageLogin(Base):
    # 点击首页登陆按钮
    def page_click(self):
        self.base_click(page.login_link)
    # 输入用户名
    def page_username(self,username):
        self.base_send_keys(page.login_username,username)
    # 输入密码
    def page_pwd(self,pwd):
        self.base_send_keys(page.login_pwd,pwd)
    # 点击登陆
    def page_login_ok_btn(self):
        self.base_click(page.login_btn_ok)
    # 错误信息
    def page_error_text(self):
        return self.base_error_text(page.login_error_text)
# 封装登陆方法
    def page_login_ways(self,value,pwd):
        time.sleep(2)
        self.page_username(value)
        time.sleep(2)
        self.page_pwd(pwd)
        time.sleep(2)
        self.page_login_ok_btn()

scripts中run.py代码(运行test代码):

import time
import unittest

from tool.HTMLTestRunner import HTMLTestRunner

suite = unittest.defaultTestLoader.discover("./")
# 报告生成目录及文件名称
dir_path = "../report/{}.html".format(time.strftime("%Y_%m_%d %H_%M_%S"))
# 获取文件流并调用run运行
with open(dir_path, "wb") as f:
    HTMLTestRunner(stream=f, title="Tpshop商城自动化测试报告", description="操作系统:win10").run(suite)

scripts中TestLogin.py代码:

import unittest
from parameterized import parameterized
from page.pageLogin import PageLogin


def get_date():
    return [('1596263494','123123',"用户名或密码有误,请重新输入或"),(' ','123123',"请您输入手机号/用户名/邮箱")]

class TestLogin(unittest.TestCase):
    login = None
    @classmethod
    def setUpClass(cls):
        cls.login = PageLogin()
        cls.login.page_click()
    @classmethod
    def tearDownClass(cls):
        cls.login.driver.quit()
    @parameterized.expand(get_date())
    def testLogin(self,value,pwd,expand):
        self.login.page_login_ways(value,pwd)
        msg = self.login.page_error_text()
        try:
            self.assertEqual(msg, expand)
        except AssertionError:
            self.login.base_screenshot_as_file()

tool包中HTMLTestRunner.py文件获取方式:

链接:https://pan.baidu.com/s/1QjZwdKvXhXNk9KYTBsm9hw 
提取码:f9zq


版权声明:本文为m0_60225699原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。