Python+Selenium+Unittest实现PO模式web自动化框架(2)
1.Common目录下的具体模块讲解。
2.basepage.py
basepage.py模块里面是封装的对元素的操作。例如:查找元素、点击元素、文本输入等等。
- # --^_^-- coding:utf-8 --^_^--
- # @Remark:webdriver的封装
- from Common import logger
- import logging
- import time
- import datetime
- from selenium.webdriver.support.wait import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
- from Common.dir_config import screenshot_dir
- from selenium.webdriver.common.action_chains import ActionChains
- from selenium.webdriver.support.select import Select
- import win32gui
- import win32con
- class BasePage:
- '''
- 包含了PageObjects当中,用到所有的selenium底层方法。
- 还可以包含通用的一些元素操作,如alert,iframe,windows...
- 还可以自己额外封装一些web相关的断言
- 实现日志记录、实现失败截图
- '''
- def __init__(self,driver):
- self.driver = driver
- # 实现网页截图操作
- def save_web_screenshot(self,img_doc):
- # 页面_功能_时间.png
- now = time.strftime("%Y-%m-%d %H_%M_%S")
- filepath = "{}-{}.png".format(now,img_doc)
- try:
- self.driver.save_screenshot(screenshot_dir + "/" + filepath)
- logging.info("网页截图成功!图片存储在:{}!".format(screenshot_dir +"/" + filepath))
- except:
- logging.exception("网页截图失败!")
- raise
- # 等待元素可见
- def wait_eleVisible(self,loc,img_doc="",timeout=30,frequency=0.5):
- logging.info("等待元素{}可见!".format(loc))
- try:
- # 起始等待的时间datetime
- startTime = datetime.datetime.now()
- # 等待元素
- WebDriverWait(self.driver,timeout,frequency).until(EC.visibility_of_element_located)
- # 结束等待时间
- endTime = datetime.datetime.now()
- logging.info("等待元素成功!开始等待时间:{},结束等待时间:{},等待时长为:{}!".format(startTime, endTime, endTime - startTime))
- except:
- # 日志
- logging.exception("等待元素可见失败!")
- # 截图-哪一个页面哪一个操作导致的失败 + 当前时间
- self.save_web_screenshot(img_doc)
- raise
- # 查找一个元素
- def get_element(self, loc, img_doc=""):
- '''
- :param loc: 元素定位,以元组的形式。(定位类型、定位时间)
- :param img_doc:截图的说明。例如:登录页面_输入用户名
- :return:webElement对象。
- '''
- logging.info("查找{}中的元素{}".format(img_doc, loc))
- try:
- ele = self.driver.find_element(*loc)
- logging.info("查找{}元素成功!".format(ele))
- return ele
- except:
- # 日志
- logging.exception("查找元素失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 等待元素出现,点击元素
- def click_element(self, loc, img_doc,timeout=30, frequency=0.5):
- '''
- :param loc:元素定位,以元组的形式。(定位类型、定位时间)
- :param img_doc:截图的说明。例如:登录页面_输入用户名
- :param timeout:等待元素的超时上限
- :param frequency:等待元素可见时,轮询周期
- :return:
- '''
- # 等待元素可见
- self.wait_eleVisible(loc, img_doc, timeout, frequency)
- # 查找元素
- ele = self.get_element(loc, img_doc)
- # 点击操作
- logging.info("点击元素{}!".format(loc))
- try:
- ele.click()
- logging.info("点击元素{}成功!".format(ele))
- except:
- # 日志
- logging.exception("点击元素失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 文本输入
- def input_text(self, loc, img_doc, *args):
- '''
- 等待元素可见,找到元素,并在元素中输入文本信息
- :param loc:元组形式的元素定位表达式
- :param img_doc:执行失败时,截图的文件命名
- :param args:输入操作中,可以输入多个值,也可以组合按键
- :return:
- '''
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找元素
- ele = self.get_element(loc, img_doc)
- # 清空输入框内容
- self.clear_data(loc,img_doc)
- # 文本输入
- logging.info("给元素{}输入文本内容:{}".format(loc, *args))
- try:
- ele.send_keys(*args)
- logging.info("文本输入成功!")
- except:
- # 日志
- logging.exception("文本输入失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 获取元素的属性值
- def get_element_attribute(self, loc, attr_name, img_doc):
- '''
- 获取元素标签的内容
- :param loc:元素定位,以元组的形式。(定位类型、定位时间)
- :param attr_name:属性名称
- :param img_doc:执行失败时,截图的文件命名
- :return:
- '''
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找元素
- ele = self.get_element(loc, img_doc)
- # 获取属性
- try:
- attr_value = ele.get_attribute(attr_name)
- logging.info("获取元素{}的属性{}值为:{}!".format(loc, attr_name, attr_value))
- return attr_value
- except:
- # 日志
- logging.exception("获取元素属性失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 获取元素的文本值
- def get_element_text(self, loc, img_doc):
- '''
- :param loc:元素定位,以元组的形式。(定位类型、定位时间)
- :param img_doc:执行失败时,截图的文件命名
- :return:
- '''
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找元素
- ele = self.get_element(loc,img_doc)
- # 获取文本值
- try:
- text = ele.text
- logging.info("获取元素{}的文本值为:{}!".format(loc, text))
- return text
- except:
- # 日志
- logging.exception("获取元素文本值失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 鼠标悬浮操作
- def mouse_suspension(self,loc, img_doc):
- # 实例化ActionChains
- ac = ActionChains(self.driver)
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找元素
- ele = self.get_element(loc)
- # 鼠标悬浮
- try:
- ac.move_to_element(ele).perform()
- time.sleep(1)
- logging.info("鼠标悬浮成功!")
- except:
- # 日志
- logging.exception("鼠标悬浮失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 进入到iframe中
- def get_iframe(self,loc,img_doc):
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找元素
- ele = self.get_element(loc)
- # 进入iframe
- try:
- self.driver.switch_to.frame(ele)
- logging.info("进入iframe中成功!")
- except:
- # 日志
- logging.exception("进入到iframe中失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 通过文本选择下拉选择框
- def drop_down_select(self,loc,text,img_doc):
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找select元素
- ele = self.get_element(loc)
- # 下拉选择
- try:
- Select(ele.select_by_visible_text(text))
- logging.info("选择select成功!")
- except:
- # 日志
- logging.exception("下拉选择失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 选择非select的下拉选择框
- def drop_down_not_select(self,loc1,loc2,img_doc):
- # 先定位到下拉菜单
- # 等待元素出现
- self.wait_eleVisible(loc1, img_doc)
- # 查找下拉菜单元素
- self.click_element(loc1,"下拉菜单输入框")
- logging.info("查找下拉菜单输入框成功!")
- time.sleep(2)
- # 在对下拉菜单的选项进行选择
- try:
- # 选择下拉菜单选项
- # 等待元素出现
- self.wait_eleVisible(loc2, img_doc)
- self.click_element(loc2,"选择下拉菜单选项")
- logging.info("选择下拉菜单成功!")
- except:
- # 日志
- logging.exception("下拉选择失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 清空输入框中的内容
- def clear_data(self,loc,img_doc):
- # 等待元素出现
- self.wait_eleVisible(loc, img_doc)
- # 查找一个元素
- ele = self.get_element(loc)
- # 清空输入框
- try:
- ele.clear()
- logging.info("清空输入框成功!")
- except:
- # 日志
- logging.exception("清空输入框失败!")
- # 截图
- self.save_web_screenshot(img_doc)
- raise
- # 上传操作(前提 :windows上传窗口已经出现。sleep1-2秒等待弹出的出现。)
- def upload(filePath, browser_type="chrome"):
- if browser_type == "chrome":
- title = "打开"
- else:
- title = ""
- # 找元素
- # 一级窗口"#32770","打开"
- dialog = win32gui.FindWindow("#32770", title)
- ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) # 二级
- comboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, "ComboBox", None) # 三级
- # 编辑按钮
- edit = win32gui.FindWindowEx(comboBox, 0, 'Edit', None) # 四级
- # 打开按钮
- button = win32gui.FindWindowEx(dialog, 0, 'Button', "打开(&O)") # 四级
- # 往编辑当中,输入文件路径.
- win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, filePath) # 发送文件路径
- win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 点击打开按钮
3.dir_config.py
dir_config.py模块里面封装的是项目当中需要用到的路径配置,该配置是相对项目来说的相对配置,这样项目无论放在哪里都能使用而不报错。
- # --^_^-- coding:utf-8 --^_^--
- # @Remark:路径配置
- import os
- # 框架项目顶层目录
- base_dir = os.path.split(os.path.split(os.path.abspath(__file__))[0])[0]
- # 日志目录
- logs_dir = os.path.join(base_dir, "Outputs/logs")
- # 截屏目录
- screenshot_dir = os.path.join(base_dir, "Outputs/screenshots")
- # 测试数据目录
- testdatas_dir = os.path.join(base_dir, "TestDatas")
- # 测试用例目录
- testcases_dir = os.path.join(base_dir, "TestCases")
- # 测试报告目录
- htmlreport_dir = os.path.join(base_dir, "Outputs/reports")
4.HTMLTestRunnerNew.py
HTMLTestRunnerNew.py模块是用于生成HTML的测试报告模块。(具体的模块代码太长,不方便展示。有需要可私聊。)
5.logger.py
logger.py模块是自定义的log日志模块。
- # --^_^-- coding:utf-8 --^_^--
- # @Remark:日志模块
- import logging
- from logging.handlers import TimedRotatingFileHandler
- import datetime
- from Common import dir_config
- fmt = "%(asctime)s %(levelname)s %(filename)s %(funcName)s [ line:%(lineno)d ] %(message)s"
- datefmt = "%Y-%m-%d %H:%M:%S"
- # 获取当前时间
- now_time = datetime.datetime.now().strftime('%Y-%m-%d')
- # 把当前时间转换成str
- now_time_str = str(now_time)
- handler_1 = logging.StreamHandler()
- handler_2 = TimedRotatingFileHandler(dir_config.logs_dir + "/" + now_time_str + "_Web.log", when='D', interval=10,backupCount=0, encoding='utf-8')
- # 设置rootlogger 的输出内容形式,输出渠道
- logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO, handlers=[handler_1, handler_2])
Python+Selenium+Unittest实现PO模式web自动化框架(2)的更多相关文章
- Python+Selenium+Unittest实现PO模式web自动化框架(1)
1.什么是PO模式? PO是Page Object的缩写 PO模式是自动化测试项目开发实践的最佳设计模式之一,讲页面定位和业务操作分开,也就是把对象的定位和测试脚本分开,从而提供可维护性. 主要有以下 ...
- Python+Selenium+Unittest实现PO模式web自动化框架(8)
1.main.py模块的功能 最后就是要有一个项目入口,并且是需要加载测试用例集. # --^_^-- coding:utf-8 --^_^-- # @Remark:运行入口 "" ...
- Python+Selenium+Unittest实现PO模式web自动化框架(6)
1.TestCases目录下的模块 TestCases目录下是存放测试用例的目录. TestCases目录下的测试用例采用unittest框架来构建. 例如:登录功能的测试用例.(test_1_log ...
- Python+Selenium+Unittest实现PO模式web自动化框架(4)
1.PageLocators目录下的具体模块 2.PageLocators目录下主要放置个页面的元素定位.用于统一管理个页面的定位元素. 例如:登录页面的元素定位login_page_locator. ...
- Python+Selenium+Unittest实现PO模式web自动化框架(7)
1.TestDatas目录的功能 TestDatas目录下存放的是测试数据,比如:登录功能的测试用例数据. # --^_^-- coding:utf-8 --^_^-- # @Remark:登录测试数 ...
- Python+Selenium+Unittest实现PO模式web自动化框架(5)
1.PageObjects目录下的模块 该目录下是存放各页面功能点. 比如:login_page.py模块下就是存放登录页面上的各个功能点的.(登录功能.获取登录失败的提示信息) # --^_^-- ...
- Python+Selenium+Unittest实现PO模式web自动化框架(3)
1.Outputs目录下的具体目录功能 2.logs目录 logs目录是用于存放log日志的一个目录. 2.reports目录 reports目录是用于存放测试报告的. 3.screenshots目录 ...
- python + selenium + unittest实现简单的UI自动化
使用的版本是python 3,其中HTMLTestRunner是修改版本,参考以下博客并下载 https://blog.csdn.net/zhanin123/article/details/78950 ...
- 【转】基于Selenium的web自动化框架(python)
1 什么是selenium Selenium 是一个基于浏览器的自动化工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.Sel ...
随机推荐
- C# HTML帮助类 包括补全标签 截取HTML字符串包含标签
public static class HtmlHelper { /// <summary> /// 按文本内容长度截取HTML字符串(支持截取带HTML代码样式的字符串) /// < ...
- 编译nginx增加fair模块
安装必要的软件 ubuntu里是 apt install wget gcc make zlib1g-dev libpcre3-dev 去官网下载最新稳定版的nginx源码 git clone 源码 g ...
- Azure Terraform(二)语法详解
一,引言 上篇文章开始,我们简单介绍了以下通过基础设施管理工具----- Terraform,通过它来统一管理复杂的云基础设施资源.作为入门演示,使用Terraform 部署Azure 资源组的方式直 ...
- 看起来很唬人,然而却简单实用的CAP理论
在做分布式系统开发时,经常会或多或少的听到CAP理论.或者是处理节点间数据一致性的问题.CAP理论很简单,但却是很多软件设计的宏观指导,因此也有人将之称为架构师必须掌握的理论之一.鉴于理论的东西相对来 ...
- [LeetCode]147. Insertion Sort List链表排序
插入排序的基本思想 把排好的放在一个新的变量中,每次拿出新的,排进去 这个新的变量要有超前节点,因为第一个节点可能会有变动 public ListNode insertionSortList(List ...
- ServletContext的作用
一个项目只有一个ServletContext对象,一个tomcat有多个项目 作用:在多核Servlet中来获取这个唯一的对象,使用ta给多个Servlet传递数据. 在Tomcat启动时创建,在To ...
- css 自定义悬浮窗写法
HTML: css(sass): 复制代码 .info { } &:hover::after { content: attr(data-title); display: inline-bloc ...
- Java JVM——8.堆
堆的核心概念 堆针对一个 JVM 进程来说是唯一的,也就是一个进程只有一个JVM,但是进程包含多个线程,他们是共享同一堆空间的. 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域. J ...
- ThreadLocal解决什么问题
原创文章,转载请务必将下面这段话置于文章开头处(保留超链接).本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ ThreadLocal解决 ...
- 日常入坑1-Calendar类
1.当前时间是一号的时候,通过计算上一天的日期的时候,需要注意了 Calendar calendar = Calendar.getInstance();calendar.set(2019,10,1); ...