基于POM的自动化测试框架

目的:总结基于POM设计方式最基础的自动化测试框架,只介绍使用到的技术

1. POM

1.1 POM 的基本概念
  • 页面对象:每个页面或页面的一部分都有一个对应的类,这个类封装了页面的元素和操作方法。
  • 测试用例:测试用例使用页面对象来执行操作和验证结果。
1.2 POM 的优势
  • 可维护性:页面对象封装了页面的元素定位和操作逻辑,页面变化时只需修改页面对象类,而不需要修改测试用例。
  • 可读性:测试用例更加简洁,易于理解。
  • 可重用性:页面对象可以在多个测试用例中重用
1.3 POM 的扩展

随着项目的复杂性增加,可以进一步扩展 POM 模式:

  • Base Page:创建一个基础页面类,封装一些常用的操作方法和属性,其他页面类继承这个基础类。
  • 组件对象:对于页面上的重复组件(如导航栏、页脚等),可以创建组件对象类,封装组件的操作方法。
  • 页面工厂:使用页面工厂模式创建页面对象,简化页面对象的实例化过程。
1.4 示例
from selenium.webdriver.common.by import By

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, "username")
        self.password_input = (By.ID, "password")
        self.login_button = (By.ID, "login")

    def enter_username(self, username):
        self.driver.find_element(*self.username_input).send_keys(username)

    def enter_password(self, password):
        self.driver.find_element(*self.password_input).send_keys(password)

    def click_login(self):
        self.driver.find_element(*self.login_button).click()

2. selenium

2.1 selenium介绍

selenium是一种UI自动化工具,包含:

  • selenium IDEA:自动录制脚本
  • Webdriver:实现不同浏览器驱动,从而操纵浏览器的行为
  • selenium grid:允许在不同的机器上并行运行不同的浏览器
2.2 安装
pip install selenium
2.3 浏览器操作
选择浏览器驱动
driver = webdriver.Chrome()
进入网页
driver.get("https://www.baidu.com/")
网页最大/小化
driver.maximize_window()
driver.minimize_window()
获取当前标签页的title
driver.title
获取当前标签页的url
driver.current_url
前进
driver.forward()
后退
driver.back()
刷新
driver.refresh()
关闭
driver.close()
滚动到顶部
driver.execute_script("window.scrollTo(0, 0);")
滚动到底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
鼠标悬停
ActionChains(driver).move_to_element(ele).perform()
寻找元素
driver.find_element(定位方式, '元素定位值')
寻找元素集
driver.find_elements(定位方式,)
2.4 元素定位

  这里只介绍通过By方式定位,并且使用显式等待法,等待该元素加载出来。

import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
driver.maximize_window()

ele = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.ID, 's-top-loginbtn')))
ele.click()
time.sleep(1)
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.ID, 'TANGRAM__PSP_11__userName')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.NAME, 'userName')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CLASS_NAME, 'pass-text-input.pass-text-input-userName')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.XPATH, '//*[@id="TANGRAM__PSP_11__userName"]')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[6]/div[2]/div[2]/div/div/div/div/div/div[1]/div[2]/form/p[3]/input[2]')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.LINK_TEXT, 'xxxxx')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, 'xxxxx')))


ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#TANGRAM__PSP_11__userName')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[name="userName"]')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.pass-text-input.pass-text-input-userName')))
ele1 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.pass-text-input.pass-text-input-userName')))


# 定位用户输入框
# input_box = driver.find_element(By.ID, 'auto-id-1723364062172')
ele1.send_keys("1222222222")
time.sleep(1)
2.4 元素操作
元素点击
ele1.click()
获取元素属性
ele1.get_attribute('属性名字')
元素清空
ele1.clear()
表单提交
ele1.submit()
元素是否被选择
ele1.is_selected()
元素是否被使能
ele1.is_enabled()
输入框输入
ele1.send_keys("txt")
2.5 元素等待
Selenium 等待
(1)强制等待
操作:time.sleep(3)
缺点:强制等待,不管在规定时间内是否执行完成,都在等待
(2)隐式等待
优点:整个周期只需要设置一次,在规定时间内,整个网页都加载完成,才能执行下一步,否则会抛出异常。相当于全局设定。
缺点:必须等待整个页面加载完成才能下一步,有些非必要元素加载较慢,则会影响执行时间。
操作:driver.implicitly_wait(20)
(3)显式等待:
优点:给局部元素设置等待时间,定位到之后可以执行下一步。
操作:element = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))

3. pytest

3.1 安装
pip install pytest
3.2 命名方式
文件命名
    测试文件通常以 test_ 开头或 _test 结尾。例如:
        test_example.py
        example_test.py
函数命名
    测试函数应以 test_ 开头。例如:
        def test_addition():
        def test_subtraction():
类命名
    类名应以 Test 开头,但不需要继承任何类。不能有__init__方法。例如:
        class TestMathOperations:
            def test_addition(self):
                assert 1 + 1 == 2

            def test_subtraction(self):
                assert 2 - 1 == 1
3.3 夹具pytest Fixtures

作用:用于在测试函数运行之前准备一些必要的环境或数据。在yield之前执行测试函数的前置操作,比如登陆等。接着使用yeild执行具体的测试函数。最后执行后置操作,清除数据等。

    @pytest.fixture(scope="function", autouse=True)
     def setup_teardown(self, request, driver):
        print("============执行前置操作===========")
        yield
        print("============执行后置操作===========")
        driver.delete_all_cookies()
        driver.refresh()
        print("清空cookies,退出登录状态")

 参数化驱动测试用例:

login_data = [
    ('user1', '12345678', True),
    ('user2', '12345678', False),
]

具体测试函数: 

@pytest.mark.parametrize("username,pwd,expected", login_data)
def test_login(self, username, pwd, expected):
        print(f"Testing with: {username}, {pwd}, {expected}")
        xxxxx具体执行
        assert flag == expected, "用户登陆测试失败"
3.4 confest.py

该文件和测试用例属于同一目录,测试执行前会先执行该文件。名称固定,不能修改。

3.5 allure报告

可以安装allure输出报告

4. 项目结构

├── Logs:日志文件
├── common:公共方法
│   ├── __init__.py
│   ├── base_page.py
│   └── log.py
├── config:基础配置,数据库、用户名等
│   └── config.yaml
├── doc:接口文档
├── tests:测试用例
│   ├── __init__.py
│   ├── conftest.py
│   ├── data:测试数据文件夹
│   └── test_login_pom.py
├── pages:页面封装对象
│   ├── __init__.py
│   ├── login_page.py
│   └── home_page.py
├── pytest.ini:pytest参数配置
├── readme.md
├── reports:allure报告
│   └── allure-results
├── requirements.txt
├── utils:基础方法
│   └── load_data.py

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值