随时可以调用公共方法的Selenium项目实战

2644 篇文章 26 订阅
2400 篇文章 14 订阅

之前写的代码中都没有加入异常处理、规范写法,应该在每次查找元素或操作时加上异常处理、日志信息、失败截图等,如下:

def input_account(self, account):
        '''输入账号'''
        try:
            WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located(self.account))
            self.driver.find_element(*self.account).send_keys(account)
        except Exception:
            raise

但是为所有的查找元素和操作都加上这些耗时且不方便维护,为了简化操作,可以把一些公用的方法封装到 BasePage 类,其它页面 page 直接继承 BasePage 即可调用公共方法。

但是为所有的查找元素和操作都加上这些耗时且不方便维护,为了简化操作,可以把一些公用的方法封装到 BasePage 类,其它页面 page 直接继承 BasePage 即可调用公共方法。

BasePage 类

1. 封装基本函数:执行日志、失败截图、异常处理等。

2. 所有页面公共操作方法。

文件结构:

 示例代码:

base_page.py
import os
import time
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from common.logger import logger
import configs
class BasePage:
    def __init__(self, driver):
        self.driver = driver
    def open(self, url):
        self.driver.get(url)
    def wait_ele_visible(self, locator:tuple, doc="", timeout=30, poll_frequency=0.5, ignored_exceptions=None):
        '''
        等待元素可见
        :param locator: 元素定位方式,元组形式
        :param timeout: 超时时间,默认30秒
        :param poll_frequency: 轮询时间,默认0.5秒
        :param ignored_exceptions: 要忽略的异常
        :param doc: 截图模块名称,若没有则只以时间戳明明
        :return:
        '''
        logger.info(f"等待元素 {locator} 可见")
        try:
            WebDriverWait(self.driver, timeout, poll_frequency, ignored_exceptions).until(EC.visibility_of_element_located(locator))
        except Exception as e:
            logger.exception(f"等待元素 {locator} 可见失败")
            self.save_screenshot(doc)
            raise e
    # 查找元素
    def get_element(self, locator: tuple, doc="")->WebElement:
        logger.info(f"查找元素 {locator} ")
        try:
            return self.driver.find_element(*locator)
        except:
            logger.exception(f"查找元素 {locator} 失败")
            self.save_screenshot(doc)
            raise
    # 点击元素
    def click_element(self, locator:tuple, doc=""):
        ele = self.get_element(locator, doc)
        try:
            ele.click()
        except:
            logger.exception(f"点击元素 {locator} 失败")
            self.save_screenshot(doc)
            raise
    # 输入文本
    def input_text(self, locator:tuple, text, doc=""):
        ele = self.get_element(locator, doc)
        try:
            ele.send_keys(text)
        except:
            logger.exception(f"元素 {locator} 输入文本 {text} 失败")
            self.save_screenshot(doc)
            raise
               # iframe 切换

    def switch_to_iframe(self, locator:tuple, doc=""):

        ele = self.get_element(locator, doc)

        try:

            self.driver.switch_to.frame(ele)

        except:

            logger.exception(f"切换到iframe {locator} 失败")

            self.save_screenshot(doc)

            raise

    # 失败截图

    def save_screenshot(self, filename):

        if not os.path.exists(configs.SCREENSHOT_PATH):

            os.mkdir(configs.SCREENSHOT_PATH)

        # 图片名称:模块名-页面名-函数名-年月日时分秒.png

        file_name = configs.SCREENSHOT_PATH + filename + "_" + time.strftime("%Y%m%d%H%M%S") + ".png"

        self.driver.save_screenshot(file_name)

        logger.info(f"成功获取截图,路径:{file_name}")

demo_login_page.py,页面 page 类需继承 BasePage 类:

import os
from configparser import ConfigParser
from common.base_page import BasePage
class LoginPage(BasePage):
    def get_locator(self):
        conf = ConfigParser()
        print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "\\page_locator\\demo_locator.ini")
        conf.read(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "\\page_locator\\demo_locator.ini", encoding="utf-8")
        self.url = conf.get("Base", "url")
        section = "LoginPageLocator"
        # eval 将字符串元组转换为元组
        self.login_by_pwd_btn = eval(conf.get(section, "login_by_pwd_btn"))
        self.account = eval(conf.get(section, "account"))
        self.pwd = eval(conf.get(section, "pwd"))
        self.login_btn = eval(conf.get(section, "login_btn"))
    def __init__(self, driver):
        super().__init__(driver)
        self.get_locator()
    def login(self, account, password):
        doc = "登录页面_登录"
        self.driver.get(self.url)                   # 打开登录页面
        self.click_element(self.login_by_pwd_btn, doc)    # 点击密码登录
        self.input_text(self.account, account, doc)  # 输入账号
        self.input_text(self.pwd, password, doc)     # 输入密码
        self.click_element(self.login_btn, doc)      # 点击登录

demo_home_page.py,页面 page 类需继承 BasePage 类:


import os
from configparser import ConfigParser
from common.base_page import BasePage
class HomePage(BasePage):
    def get_locator(self):
        conf = ConfigParser()
        conf.read(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "\\page_locator\\demo_locator.ini",encoding="utf-8")
        section = "HomePageLocator"
        self.account_info = eval(conf.get(section, "account_info"))
    def __init__(self, driver):
        super().__init__(driver)
        self.get_locator()
    def is_account_info_exist(self):
        try:
            self.wait_ele_visible(self.account_info)
            return True
        except Exception:
            return False

test_demo.py:


from pytest_assume.plugin import assume
from selenium import webdriver
from po.page_object.demo_home_page import HomePage
from po.page_object.demo_login_page import LoginPage
class TestLogin():
    def setup_class(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)
    def teardown_class(self):
        self.driver.quit()
    def test_demo(self):
        self.login_page = LoginPage(self.driver)
        self.home_page = HomePage(self.driver)
        self.login_page.login("15348369418", "Pan910124")
        with assume:
            assert self.home_page.is_account_info_exist()

对于一些通用的方法,我们也可根据自己的需要进行封装,譬如从 demo_locator.ini 文件获取数据,我们可以封装一个工具类 handle_ini.py 放在 common 模块下:

import os
from configparser import ConfigParser
class HandleIni(ConfigParser):
    # 已字典格式返回 ini 文件中某个 section 的数据
    def get_locator_dict(self, locator_file, section):
        conf = ConfigParser()
        conf.read(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "\\po\\page_locator\\" + locator_file, encoding="utf-8")
        section_data = {}
        for key in conf.options(section):
            section_data[key] = conf.get(section, key)
        return section_data

那么其他页面类就可以使用 HandleIni 工具类来获取数据:


# demo_home_page.py
from common.base_page import BasePage
from common.handle_ini import HandleIni
class HomePage(BasePage):
    def get_locator(self):
        locators = HandleIni().get_locator_dict("demo_locator.ini", "HomePageLocator")
        self.account_info = eval(locators.get("account_info"))
    def __init__(self, driver):
        super().__init__(driver)
        self.get_locator()
    def is_account_info_exist(self):
        try:
            self.wait_ele_visible(self.account_info)
            return True
        except Exception:
            return False

资源分享【这份资料必须领取~

下方这份完整的软件测试视频学习教程已经上传CSDN官方认证的二维码,朋友们如果需要可以自行免费领取 【保证100%免费】

 

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:课程介绍你是否在寻找机会进入自动化测试领域?你是否渴望学习selenium webdriver + Java以及**的框架和技术进行web自动化测试?你是否感兴趣学习Selenium如何用在你现有的项目里的?这门课带你从Selenium搭建环境开始讲起,然后学习常用方法,单元测试,PO设计模式, jenkins等。我们假设学员没有任何自动化经验,来设计的这套课程。每个课题都从最基础的开始讲起。Selenium相关的该覆盖的课题都覆盖了。全程手写代码,逐步迭代,方便学习。例子都是来自于真实的web应用项目,帮助你理解不同的组件怎么用上自动化,这将展示给你一个行业层面的框架,增加自信心。这门课涵盖到基础到高级项目实战。您将会学到什么学完课程以后,你将了解Selenium Webdriver知识你将具备设计数据驱动框架、Page Object、等搭建自动化框架的能力用众多实例对Selenium现实场景应用进行深入理解了解单元测试, Jenkins, HTML报告,并发测试 你从网上随便选择一个网站,都可以尝试实现自动化,用所有可能的测试用例进行自动化测试将提高你的编码技能,以编写最优化的自动化测试用例代码你基本可以应对任何Selenium面试,并能从设计阶段开始领导整个Selenium自动化项目你将能够创建漂亮的报告来打动客户或领导更深入地理解自动化指南和代码质量标准会附带一个练习网站,可以用上所有可用的WebDriver功能,实现自动化【适合人群】软件手动测试人员想转为自动化测试的人员自动化软件测试人员想加强专业技能的刚毕业学生想从事软件行业QA 组长或项目经理【课程优势】学完课程以后,你将拥有完整的Selenium Webdriver知识,完整的项目实战【讲师介绍】资质介绍:12年以上开发、自动测试方面经验,其中7年以上测试开发经验,现为技术架构师新书“Python3+Selenium3自动化测试项目实战”作者【课程咨询】作者联系QQ:2574674466 完善的学习文档            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值