吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3551|回复: 22
收起左侧

[Python 转载] Python+selenium UI自动化一个小模式

[复制链接]
只有午安 发表于 2021-8-12 10:35
本帖最后由 只有午安 于 2021-8-12 10:46 编辑

来了这么久,看了很多帖子,都没有发现有UI自动化这个东西,本人测试行业,最近也自己在学习这个东西,就发出来到目前写的一起学习一下吧,最好有大佬提供一下框架的思路。
这个是模式是我在网上找的一个叫PO模式(Page Objects),找了很多,个人觉得这个模式还可以。有不对的地方请大佬指正。{:301_993:}

PO模式介绍
用官话说它是selenium中的一种页面对象设计模式(不是测试框架!是一种开展ui自动化测试的思想),把ui自动化测试中的每个页面抽象出来,将每个页面用到的业务逻辑(page类)和页面元素(locator类)各自封装起来,然后编写测试用例时只需要调用每个page中的业务逻辑方法即可。测试(用例)脚本不需要关注元素的定位情况,当元素位置发生变化时,只需修改对应页面元素的locator即可

    使用页面对象模式的好处:
(1)创建可跨多个测试用例共享的可重用代码(每个测试用例只需调用page类中封装好的业务逻辑(操作)即可)。
(2)减少重复代码的数量。(如向输入框输入信息、单击操作等)
(3)如果用户界面发生变化,修改脚本只需要在一个地方进行更改。


BasePage页 (基类页,封装各种操作方法)
[Python] 纯文本查看 复制代码
# coding: utf-8

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException


class BasePage:
    """封装其他页面都会用到的方法"""
    base_url = '某宝链接'

    def __init__(self, driver):
        self.driver = driver  # 构造函数全局统一Driver

    def open(self):
        """打开页面的方法"""
        self.driver.get(self.base_url)  # 启动浏览器打开链接
        self.driver.maximize_window()  # 最大化窗口

    def find_element(self, locator):
        """定位元素的方法"""
        try:
            element = WebDriverWait(self.driver, 15).until(EC.presence_of_element_located(locator))
            return element
        except NoSuchElementException:
            print('%s 页面无 %s 元素' % (self, locator))

    def switch_frame(self, locator):
        """切换frame"""
        return self.driver.swtich_to_frame(locator)     # 切换frame后面暂未用到- -

    def send_key(self, locator, value, clear_first=True):
        """输入方法"""
        try:
            if clear_first:
                self.find_element(locator).clear()          # 清空输入框
            self.find_element(locator).send_keys(value)     # 查找元素 send内容
        except AttributeError:
            print('%s 页面无 %s 元素' % (self, locator))

    def click(self, locator):
        """点击方法"""
        self.find_element(locator).click()

    def get_current_url(self):
        """获取当前页面URL"""
        return self.driver.current_url

    def get_current_title(self):
        """获取当前页面标题"""
        return self.driver.title

    def switch_window(self):
        """
        切换窗口
        直接选择倒数第一个窗口
        后续操作才会在新窗口继续执行
        """
        nw = self.driver.window_handles
        self.driver.switch_to.window(nw[-1])
        return nw




locators页面 (存放页面内的元素位置)
[Python] 纯文本查看 复制代码
from selenium.webdriver.common.by import By


class Locators():
    """元素定位器
    元素位置改变
    这里改"""
    first_page_locators = {
        'tblogo': (By.XPATH, '//div[@class="logo"]//h1/a[1]'),
        'search': (By.XPATH, '//*[@id="J_TSearchForm"]/div[1]/button'),
        'writer': (By.ID, 'q'), # '//input[@aria-label="请输入搜索文字"]'
        'value' : "鸿星尔克"
    }


if __name__ == "__main__":
    t = Locators()
    print(t.first_page_locators['writer'])
    # print(t.first_page_locators['search'])


[Python] 纯文本查看 复制代码
Page页 (需要操作业务的页面)
from papes.BasePage import BasePage
from locators.locators import Locators


# 此页面加操作
class Firstpage(BasePage):
    value = Locators.first_page_locators["value"]
    tblogo = Locators.first_page_locators['tblogo']
    search = Locators.first_page_locators['search']
    shuru = Locators.first_page_locators['writer']

    def logo_click(self):
        """点击logo"""
        self.click(self.tblogo)

    def send_some(self):
        """输入框输入"""
        self.send_key(self.shuru, self.value)

    def search_click(self):
        """点击搜索"""
        self.click(self.search)


if __name__ == "__main__":
    t = Locators()
    print(t.first_page_locators['writer'])




t01 页 (unittest页面,也就是用例页面,直接调用page页,看起来就不会太冗余)
[Python] 纯文本查看 复制代码
import unittest
from time import sleep

from papes.Firstpage import Firstpage
from selenium import webdriver
from papes.BasePage import BasePage


class MyTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):    # 只运行一次
        print("开始测试")

    def setUp(self):        # 每运行一次用例前执行
        # 实例化类 以及 赋值,方便调用
        self.driver = webdriver.Chrome()
        self.url = BasePage.base_url
        self.page = Firstpage(self.driver)
        self.page.open()
        self.jilei = BasePage(self.driver)

    def test_1(self):       # 用例1
        """
        加点等待时间等待页面元素加载
        尽量少使用固定等待
        - -我图方便才用这么多sleep
        用多了会导致时间长点,影响效率
        """
        self.driver.implicitly_wait(15)
        sleep(3)
        self.page.logo_click()     # 调用Page页定义好的函数
        sleep(3)
        self.page.switch_window()      # 切换窗口
        print(self.driver.current_url)      # 打印当前URL
        sleep(3)
        self.page.send_some()      # 输入内容 :Send_keys:
        sleep(3)

    def tearDown(self):     # 每运行一次用例后执行
        sleep(2)
        self.driver.quit()  # 退出浏览器


if __name__ == '__main__':
    unittest.main()


免费评分

参与人数 3吾爱币 +12 热心值 +3 收起 理由
helian147 + 2 + 1 用心讨论,共获提升!
Ryan_XQ + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hangjau 发表于 2021-8-15 11:47
POM模式 这个设计的中心思想就是页面即对象。框架的话 也简单的   楼主其实已经实现了 整体框架 分为base、page、data、case、report   外加上ddt 和HTMLTestRunner 输出报告  base 做为底层所有的动作,page将定位和操作步骤分开,data 测试数据的存储。 case 具体的页面用例。 report  执行结果报告。
另外  UI自动化成本太大。还是接口的比较实用。另外这个有个弊端就是一旦项目很大的情况下 整体的自动化项目会很臃肿因为页面变多了。每一个新页面就要写一个page文件,写一个case 文件。代码量还是偏高的。
zhangxu121213 发表于 2022-1-7 10:56
Hangjau 发表于 2022-1-6 22:34
只做冒烟的话 还真不一定覆盖页面所有点击。冒烟是根据业务主流程走的,不用考虑页面其他控件。注意的话 ...

感谢您,我试试,我是第一次写ui自动化,领导并没有给出需要测试的项,按我的理解

这个系统主要作为查询使用,不同类型查询,例如,警告,黑名单,白名单。而且每一个查询的页面都是iframe,每次点击查询,都要进入和退出,并且查询项涉及到各种条件,例如时间、模糊查询、类型、型号。查询的结果是列表形式展示在页面,我之前的想法是点击一次查询(不添加任何条件)。然后判断返回的列表信息。
您看,我是不是走错了方向,
是否有更简单的方式?
 楼主| 只有午安 发表于 2021-8-12 10:38
本帖最后由 只有午安 于 2021-8-12 11:06 编辑

妥了,原来不能分页= =
SagJoker 发表于 2021-8-12 10:52
额。我好像平时也是这样做。
huajt2004 发表于 2021-8-12 12:24
谢谢分享啊
orb001 发表于 2021-8-12 12:59
谢谢分享
syy 发表于 2021-8-13 09:47
那个啥 这种帖子可以描述的更普遍化一点 就是几乎到手把手给你解释那张 看的人懂了 就给评分了
 楼主| 只有午安 发表于 2021-8-13 10:39
syy 发表于 2021-8-13 09:47
那个啥 这种帖子可以描述的更普遍化一点 就是几乎到手把手给你解释那张 看的人懂了 就给评分了

代码里该注释的都注释了,好像没啥解释的了。。。  可能我就这拉跨水平吧
Bimice 发表于 2021-8-13 13:32
过来捧个场,,有所帮助
helian147 发表于 2021-8-14 09:23
很好的通用模板,将方法,元素定位+取值都封装好了,最后直接调用即可,稍微改改具体的值就是能用爬虫,挺适用于js头大的大站
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 09:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表