自动化测试-web(PO:Page Object 模式)

一、PO模式

PO:Page Object(页面对象),将自动化涉及的页面或模块封装成对象。

PO能解决什么问题?

  1. 代码复用性
  2. 便于维护(脚本层与业务分离)--如果元素信息发生变化了,也不用去修改脚本。

PO如何做?

Base层:存放所有页面公共方法

Page层:基于页面或模块单独封装当前页面要操作的对象

Script层:脚本层+unittest

非PO模式的代码实现

import unittest
from selenium import webdriver
from time import sleep

class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome("/usr/local/bin/chromedriver")
        self.driver.maximize_window()
        self.driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        self.driver.implicitly_wait(10)

    def tearDown(self) -> None:
        sleep(5)
        self.driver.quit()

    def test01_login(self):
        self.driver.find_element_by_css_selector("#username").send_keys("13600001111")
        self.driver.find_element_by_css_selector("#password").send_keys("123456")
        self.driver.find_element_by_css_selector("#verify_code").send_keys("8888")
        self.driver.find_element_by_css_selector(".J-login-submit").click()

PO设计结构:

base:存放所有page页面公共方法

page:将页面封装为对象

script:测试脚本

案例:

base.py

"""
base类,存放所有page页面公共操作方法
"""

from selenium.webdriver.support.wait import WebDriverWait

class Base:
    def __init__(self,driver):
        self.driver = driver

    # 查找元素
    def base_find(self,loc,timeout=10,poll_frequency=0.5):
        # 显示等待->查找元素  loc=(By.ID,"#userA")
        return WebDriverWait(self.driver,timeout,poll_frequency).\
            until(lambda x:x.find_element(loc[0],loc[1]))

    # 输入方法
    def base_input(self,loc,value):
        # 获取元素
        el = self.base_find(loc)
        # 清空操作
        el.clear()
        # 输入内容
        el.send_keys(value)

    # 点击方法
    def base_click(self,loc):
        self.base_find(loc).click()

    # 获取文本值方法
    def base_get_text(self,loc):
        return self.base_find(loc).text

page_login.py

"""
模块名:page_模块
类名:大驼峰将模块移植进来,去掉下划线和数字。
方法:自动化测试当前页面要操作哪些元素,就封装哪些方法
"""
from po.base.base import Base
from selenium.webdriver.common.by import By

# 用户名
username = (By.CSS_SELECTOR,"#username")
# 密码
pwd = (By.CSS_SELECTOR,"#password")
# 验证码
verify_code = (By.CSS_SELECTOR,"#verify_code")
# 登录按钮
login_btn = (By.CSS_SELECTOR,".J-login-submit")
# 昵称
nick_name = (By.CSS_SELECTOR,".userinfo")


class PageLogin(Base):
    # 输入用户名
    def __page_username(self,value):
        self.base_input(username,value)
    # 输入密码
    def __page_pwd(self,value):
        self.base_input(pwd,value)
    # 输入验证码
    def __page_verify_code(self,value):
        self.base_input(verify_code,value)
    # 点击登录按钮
    def __page_click_login_btn(self):
        self.base_click(login_btn)
    # 获取昵称
    def page_get_nickname(self):
        return self.base_get_text(nick_name)
    # 组合业务方法(测试业务层调用此方法,便捷)
    def page_login(self,phone,password,code):
        self.__page_username(phone)
        self.__page_pwd(password)
        self.__page_verify_code(code)
        self.__page_click_login_btn()

test_login.py

import unittest
from selenium import webdriver
from po.page.page_login import PageLogin

class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome("/usr/local/bin/chromedriver")
        self.driver.maximize_window()
        self.driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        self.login = PageLogin(self.driver)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_login(self,phone="13600001111",password="123456",code="8888"):
        # 调用登录业务
        self.login.page_login(phone,password,code)
        # 断言
        nickname = self.login.page_get_nickname()
        print("nickname:",nickname)

二、数据驱动

什么是数据驱动?

  • 以测试数据驱动用例执行(测试数据和代码分离)

为什么要数据驱动?

  • 便于维护(维护的焦点从代码转到测试数据)

数据驱动如何操作?

  • 编写数据存储文件
  • 编写读取数据工具
  • 使用参数化引用

编写数据存储文件

  1. 新建json文件,在文件中编写一个{}

  2. 有几个模块,写几个key,值为列表

  3. 列表中参数化数据有几组,就写几个{}

  4. 每个{}中组成: 说明+参数数据+预期结果

    {
    "login":[
    {
    "desc":"登录成功",
    "phone":"13600001111",
    "password":"123456",
    "code":"8888",
    "except_text":"13600001111"
    }
    ]
    }

具体的代码:

json_test.json

{
    "login":[
        {
        "desc":"登录成功",
        "phone":"13600001111",
        "Password":"123456",
        "Code":"8888"
        }
    ]
}

read_json.py

import os
import json

def read_json(filename,key):
    filepath = os.path.dirname(os.path.dirname(__file__)) + os.sep + "data" + os.sep + filename
    arr = []
    with open(filepath,"r",encoding="utf-8") as f:
        for data in json.load(f).get(key):
            arr.append(tuple(data.values())[1:])
        return arr

test_login.py

import unittest
from po_test.page.page_login import PageLogin
from selenium import webdriver
from time import sleep
from parameterized import parameterized
from po_test.util.read_json import read_json

class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome("/usr/local/bin/chromedriver")
        self.driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        self.driver.maximize_window()
        self.pagelogin = PageLogin(self.driver)

    def tearDown(self) -> None:
        sleep(5)
        self.driver.quit()

    @parameterized.expand(read_json("json_test.json","login"))
    def test_login(self,phone,password,code):
        self.pagelogin.login(phone,password,code)
相关推荐
测试杂货铺16 小时前
UI自动化测试实战实例
自动化测试·软件测试·python·selenium·测试工具·测试用例·pytest
m0_7482411216 小时前
Selenium之Web元素定位
前端·selenium·测试工具
柠檬不萌只是酸i19 小时前
day19——web自动化测试(1)
selenium·测试工具
FL16238631291 天前
python版本的Selenium的下载及chrome环境搭建和简单使用
chrome·python·selenium
一条测试老狗2 天前
【UI自动化】从WebDriver看Selenium与Appium的底层关联
selenium·appium·自动化
代码的乐趣2 天前
支持selenium的chrome driver更新到131.0.6778.204
chrome·python·selenium
oneouto2 天前
selenium学习笔记(一)
笔记·学习·selenium
oneouto2 天前
selenium学习笔记(二)
笔记·学习·selenium
小白学大数据4 天前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
weixin_419349794 天前
selenium 报错 invalid argument: invalid locator
selenium·测试工具