selenium自动化之PO模型

目录

一、selenium:

1.定位:

2.加载url

3.输入

4.点击

5.清除

6.获取文本内容

7.获取属性

8.切换/窗口切换

8.1Frame切换

8.2窗口切换:

9.等待

二、logging模块简介

三、什么是PO?

1.简介

2.设计的原则

3.PO模型的实现

四、代码

4.1Logger

 4.2Base_Page

4.3报告


在讲解PO模型之前先给大家巩固下selenium与logger,代码附在了最后

一、selenium:

1.定位:

webdriver提供了18种(注意是18种,不是8种)的元素定位方法,前面8种是通过元素的属性来直接定位的,后面的xpath和css定位更加灵活,需要重点掌握其中一个。前八种是大家都熟悉的,经常会用到的:

1.id定位:find_element_by_id(self, id_)

2.name定位:find_element_by_name(self, name)

3.class定位:find_element_by_class_name(self, name)

4.tag定位:find_element_by_tag_name(self, name)

5.link定位:find_element_by_link_text(self, link_text)

6.partial_link定位find_element_by_partial_link_text(self, link_text)

7.xpath定位:find_element_by_xpath(self, xpath)

8.css定位:find_element_by_css_selector(self, css_selector)

9.id复数定位find_elements_by_id(self, id_)

10.name复数定位find_elements_by_name(self, name)

11.class复数定位find_elements_by_class_name(self, name)

12.tag复数定位find_elements_by_tag_name(self, name)

13.link复数定位find_elements_by_link_text(self, text)

14.partial_link复数定位find_elements_by_partial_link_text(self, link_text)

15.xpath复数定位find_elements_by_xpath(self, xpath)

16.css复数定位find_elements_by_css_selector(self, css_selector

17.find_element(self, by='id', value=None)

18.find_elements(self, by='id', value=None)

2.加载url

driver.get(url)

3.输入

find_element(self,loc).send_keys(text)

4.点击

find_element(self,loc).click()

5.清除

find_element(self,loc).clear()

6.获取文本内容

find_element(self,loc).text

7.获取属性

find_element(self,loc).get_attribute(name)

8.切换/窗口切换

8.1Frame切换

切换到frame

wd.switch_to.frame(frame_reference)

切回原来的主html

wd.switch_to.default_content()

8.2窗口切换:

wd.switch_to.window(handle)

9.等待

timd.sleep(固定等待)

implicitly_wait(隐式等待)

WebDriverWait(显示等待)

          #等待元素可见

WebDriverWait(self.driver,timeout,poll_frequency).until(EC.visibility_of_element_located((By.XPATH,loc)))

          #等待元素不可见

WebDriverWait(self.driver,timeout,poll_frequency).until_not(EC.visibility_of_element_located((By.XPATH,loc)))

二、logging模块简介

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;

尽管可以在Python代码中配置logging,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。在Python 2.7及以后的版本中,可以从字典中加载logging配置,也就意味着可以通过文件加载日志的配置。

然后通过logging.config.fileConfig(filename)来调用写好的配置文件,运行可以看到调用正常

三、什么是PO?

1.简介

在自动化中,Selenium自动化测试中有一个名字经常被提及PageObject(思想与面向对象的特征相同),通常PO模型可以大大提高测试用例的维护效率,页面对象模型(PO)是一种设计模式,用来管理维护一组页面元素的对象库.在PO下,应用程序的每一个页面都有一个对应的Page类.每一个Page类维护着该页面的元素集和操作这些元素的方法.怎么设计PO?

2.设计的原则

1.抽象每一个页面

2.页面中元素不暴露,仅报错操作元素的方法

3.页面不应该有繁琐的继承关系

4.页面中不是所有元素都需要涉及到,核型业务元素做建模使用

5.把页面划分功能模块,在Page中实现这些功能方法

3.PO模型的实现

专业介绍完毕,但是没接触过的小伙伴看到这些俗不可耐的介绍肯定会头蒙的,下面来跟我一起有效探索PO模型吧,本文不讲基础,只讲解思想与实现,基础还需要各位自己巩固。

我所理解的PO模型就是将一个完整的代码划分模块然后分块管理,我这边主要划分为底层封装(关键),配置文件,数据管理,输出,页面操作相关,测试用例等几个模块

详细划分如下:

下面看下对selenium封装的一个实现,

使用logger进行一个log打印,打印完之后进行元素的查找,查找完毕后打印日志表示查找成功,然后进行输入操作,若操作失败则截图保存到对应路径中,

截图代码如下,

页面操作文件(.py)

四、代码

4.1Logger

#log.conf        
[loggers]
keys=root,file,fileAndConsole
[handlers]
keys=fileHandler,consoleHandler
[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_file]
level=DEBUG
handlers=fileHandler
qualname=file
propagate=1
[logger_fileAndConsole]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=fileAndConsole
propagate=0

[handler_fileHandler]
class=FileHandler
args=(".\\OutPuts\\Log\\_log.log",'a','utf-8')
level=DEBUG
formatter=simpleFormatter

[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s %(filename)s %(levelname)s %(message)s
#define_log.py
import logging
import logging.config
from os import path
from BasePage.global_param import conf_log
#调用logging 配置文件 并打印log
class DefineLog:
    def setLoger(self):
        print(conf_log)
        #读取配置文件中的内容
        logging.config.fileConfig(conf_log)
        #选择模式输出到控制台和文件中
        logger = logging.getLogger('fileAndConsole')
        return logger

if __name__ == '__main__':
    de = DefineLog()
    logger = de.setLoger()
    #正常输出log信息
    logger.info('info')
    logger.debug('debug')

 4.2Base_Page

#Base_Page
import time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from BasePage.define_log import DefineLog
from BasePage.global_param import img_path

#基础页面操作配置 如点击、查找元素、输入。。。
class BasePage:


    def __init__(self,driver):
        self.driver = driver
        self.defineLog = DefineLog()# fileHandler,consoleHandler
        self.logger = self.defineLog.setLoger()
    #打开对应的url
    def open_url(self,url):
        self.driver.get(url)

    #等待元素可见
    def wait_element_visible(self,loc,timeout=150,poll_frequency=0.5,model=None):
        self.logger.info('{}--等待元素可见--{}'.format(model,loc))
        print(2.2)
        try:
            start = time.time()
            WebDriverWait(self.driver,timeout,poll_frequency).until(EC.visibility_of_element_located((By.XPATH,loc)))
            end = time.time()
            print('等待时长:%.2f 秒' % (end - start))

        except:
            self.save_webImage(model)
            raise
    #等待一个元素不可见
    def wait_element_no_visible(self,loc,timeout=7,poll_frequency=0.5,model=None):
        """
        :param loc: 元素定位表达(定位元素类型,元素定位方法)
        :param timeout: 等待的上限
        :param poll_frequency: 轮询频率
        :param model: 等待失败时截图操作
        :return: None
        """
        print('{}--等待元素不可见:{}'.format(model,loc))
        try:
            start = time.time()
            WebDriverWait(self.driver,timeout,poll_frequency).until_not(EC.visibility_of_element_located((By.XPATH,loc)))
            end = time.time()
            print('等待时长:%.2f 秒'%(end-start))
        except:
            print('{}等待元素不可见失败:{}'.format(model,loc))
            #截图
            self.save_webImage(model)
            raise

    #查找一个元素element
    def find_elements(self,loc,model=None):
        self.logger.info('{}--等待元素可见--{}'.format(model,loc))
        try:
            return self.driver.find_element(By.XPATH,*loc)
        except:
            print('查找元素失败')
            #截图
            self.save_webImage(model)
            raise
    #输入操作
    def input_text(self,loc,text,model=None):
        #查找元素
        element = self.driver.find_element(By.XPATH,loc)
        #打印日志
        self.logger.info('{}在元素{}中输入文本:{}'.format(model,loc,text))
        try:
            #进行输入操作
            element.send_keys(text)
        except:
            print('输入操作失败')
            #若操作失败后截图
            self.save_webImage(model)
            raise
    def send_key(self,key):
        ActionChains(self.driver).send_keys(key).perform()

    #点击操作
    def click_element(self,loc,model=None):
        #先查找元素在点击
        element = self.driver.find_element(By.XPATH,loc)
        #点击操作
        self.logger.info('{}在元素{}中点击'.format(model, loc))
        try:
            element.click()
        except:
            print('点击操作失败')
            #截图
            self.save_webImage(model)
            raise
    #清除操作
    def clean_text(self,loc,model=None):
        element = self.find_element(By.XPATH,loc)
        #清除操作
        self.logger.info('{}在元素{}中清除'.format(model,loc))
        try:
            element.clear()
        except:
            print('清除失败')
            #截图
            self.save_webImage(model)
            raise
    # 获取文本内容
    def get_text(self, loc, model=None):
        # 先查找元素在获取文本内容
        ele = self.find_element(By.XPATH,loc)
        # 获取文本
        self.logger.info('{} 在元素 {} 中获取文本'.format(model, loc))
        try:
            text = ele.text
            print('{} 元素 {} 的文本内容为 {}'.format(model, loc, text))
            return text
        except:
            print('获取元素 {} 的文本内容失败,报错信息如下:'.format(loc))
            # 截图
            self.save_webImgs(model)
            raise
    # 获取属性值
    def get_element_attribute(self, loc, name,model=None):
        # 先查找元素在去获取属性值
        ele = self.find_element(By.XPATH,loc)
        # 获取元素属性值
        self.logger.info('{} 在元素 {} 中获取属性值'.format(model, loc))
        try:
            ele_attribute = ele.get_attribute(name)
            print('{} 元素 {} 的文本内容为 {}'.format(model, loc, ele_attribute))
            return ele_attribute
        except:
            print('获取元素 {} 的属性值失败,报错信息如下:'.format(loc))
            self.save_webImgs(model)
            raise
    #截图
    def save_webImage(self,model=None):
        #filepath:图片保存目录/model(页面功能名称)_当前时间到秒.png
        filePath ='{}{}.png'.format(img_path,model)
        print(filePath)
        try:
            self.driver.save_screenshot(filePath)
            print('截图成功,图片路径为{}'.format(filePath))
        except:
            print('截屏失败!')

4.3报告

#run.py
import unittest
from BasePage.global_param import test_case_path,report_name
from HtmlTestRunner import HTMLTestRunner

"""运行文件"""
if __name__ == '__main__':
    discover = unittest.defaultTestLoader.discover(r"./",pattern='test*.py')
    with open(report_name,'w') as f:
        runner =HTMLTestRunner(stream=f,report_title='test1',report_name='result.html',verbosity=2,descriptions='运行结果')
        runner.run(discover)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇往直前的小测试

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值