1.Common目录下的具体模块讲解。

2.basepage.py

basepage.py模块里面是封装的对元素的操作。例如:查找元素、点击元素、文本输入等等。

  1. # --^_^-- coding:utf-8 --^_^--
  2. # @Remark:webdriver的封装
  3.  
  4. from Common import logger
  5. import logging
  6. import time
  7. import datetime
  8. from selenium.webdriver.support.wait import WebDriverWait
  9. from selenium.webdriver.support import expected_conditions as EC
  10. from Common.dir_config import screenshot_dir
  11. from selenium.webdriver.common.action_chains import ActionChains
  12. from selenium.webdriver.support.select import Select
  13. import win32gui
  14. import win32con
  15.  
  16. class BasePage:
  17. '''
  18. 包含了PageObjects当中,用到所有的selenium底层方法。
  19. 还可以包含通用的一些元素操作,如alert,iframe,windows...
  20. 还可以自己额外封装一些web相关的断言
  21. 实现日志记录、实现失败截图
  22. '''
  23. def __init__(self,driver):
  24. self.driver = driver
  25.  
  26. # 实现网页截图操作
  27. def save_web_screenshot(self,img_doc):
  28. # 页面_功能_时间.png
  29. now = time.strftime("%Y-%m-%d %H_%M_%S")
  30. filepath = "{}-{}.png".format(now,img_doc)
  31. try:
  32. self.driver.save_screenshot(screenshot_dir + "/" + filepath)
  33. logging.info("网页截图成功!图片存储在:{}!".format(screenshot_dir +"/" + filepath))
  34. except:
  35. logging.exception("网页截图失败!")
  36. raise
  37.  
  38. # 等待元素可见
  39. def wait_eleVisible(self,loc,img_doc="",timeout=30,frequency=0.5):
  40. logging.info("等待元素{}可见!".format(loc))
  41. try:
  42. # 起始等待的时间datetime
  43. startTime = datetime.datetime.now()
  44. # 等待元素
  45. WebDriverWait(self.driver,timeout,frequency).until(EC.visibility_of_element_located)
  46. # 结束等待时间
  47. endTime = datetime.datetime.now()
  48. logging.info("等待元素成功!开始等待时间:{},结束等待时间:{},等待时长为:{}!".format(startTime, endTime, endTime - startTime))
  49. except:
  50. # 日志
  51. logging.exception("等待元素可见失败!")
  52. # 截图-哪一个页面哪一个操作导致的失败 + 当前时间
  53. self.save_web_screenshot(img_doc)
  54. raise
  55.  
  56. # 查找一个元素
  57. def get_element(self, loc, img_doc=""):
  58. '''
  59. :param loc: 元素定位,以元组的形式。(定位类型、定位时间)
  60. :param img_doc:截图的说明。例如:登录页面_输入用户名
  61. :return:webElement对象。
  62. '''
  63. logging.info("查找{}中的元素{}".format(img_doc, loc))
  64. try:
  65. ele = self.driver.find_element(*loc)
  66. logging.info("查找{}元素成功!".format(ele))
  67. return ele
  68. except:
  69. # 日志
  70. logging.exception("查找元素失败!")
  71. # 截图
  72. self.save_web_screenshot(img_doc)
  73. raise
  74.  
  75. # 等待元素出现,点击元素
  76. def click_element(self, loc, img_doc,timeout=30, frequency=0.5):
  77. '''
  78. :param loc:元素定位,以元组的形式。(定位类型、定位时间)
  79. :param img_doc:截图的说明。例如:登录页面_输入用户名
  80. :param timeout:等待元素的超时上限
  81. :param frequency:等待元素可见时,轮询周期
  82. :return:
  83. '''
  84. # 等待元素可见
  85. self.wait_eleVisible(loc, img_doc, timeout, frequency)
  86. # 查找元素
  87. ele = self.get_element(loc, img_doc)
  88. # 点击操作
  89. logging.info("点击元素{}!".format(loc))
  90. try:
  91. ele.click()
  92. logging.info("点击元素{}成功!".format(ele))
  93. except:
  94. # 日志
  95. logging.exception("点击元素失败!")
  96. # 截图
  97. self.save_web_screenshot(img_doc)
  98. raise
  99.  
  100. # 文本输入
  101. def input_text(self, loc, img_doc, *args):
  102. '''
  103. 等待元素可见,找到元素,并在元素中输入文本信息
  104. :param loc:元组形式的元素定位表达式
  105. :param img_doc:执行失败时,截图的文件命名
  106. :param args:输入操作中,可以输入多个值,也可以组合按键
  107. :return:
  108. '''
  109. # 等待元素出现
  110. self.wait_eleVisible(loc, img_doc)
  111. # 查找元素
  112. ele = self.get_element(loc, img_doc)
  113. # 清空输入框内容
  114. self.clear_data(loc,img_doc)
  115. # 文本输入
  116. logging.info("给元素{}输入文本内容:{}".format(loc, *args))
  117. try:
  118. ele.send_keys(*args)
  119. logging.info("文本输入成功!")
  120. except:
  121. # 日志
  122. logging.exception("文本输入失败!")
  123. # 截图
  124. self.save_web_screenshot(img_doc)
  125. raise
  126.  
  127. # 获取元素的属性值
  128. def get_element_attribute(self, loc, attr_name, img_doc):
  129. '''
  130. 获取元素标签的内容
  131. :param loc:元素定位,以元组的形式。(定位类型、定位时间)
  132. :param attr_name:属性名称
  133. :param img_doc:执行失败时,截图的文件命名
  134. :return:
  135. '''
  136. # 等待元素出现
  137. self.wait_eleVisible(loc, img_doc)
  138. # 查找元素
  139. ele = self.get_element(loc, img_doc)
  140. # 获取属性
  141. try:
  142. attr_value = ele.get_attribute(attr_name)
  143. logging.info("获取元素{}的属性{}值为:{}!".format(loc, attr_name, attr_value))
  144. return attr_value
  145. except:
  146. # 日志
  147. logging.exception("获取元素属性失败!")
  148. # 截图
  149. self.save_web_screenshot(img_doc)
  150. raise
  151.  
  152. # 获取元素的文本值
  153. def get_element_text(self, loc, img_doc):
  154. '''
  155. :param loc:元素定位,以元组的形式。(定位类型、定位时间)
  156. :param img_doc:执行失败时,截图的文件命名
  157. :return:
  158. '''
  159. # 等待元素出现
  160. self.wait_eleVisible(loc, img_doc)
  161. # 查找元素
  162. ele = self.get_element(loc,img_doc)
  163. # 获取文本值
  164. try:
  165. text = ele.text
  166. logging.info("获取元素{}的文本值为:{}!".format(loc, text))
  167. return text
  168. except:
  169. # 日志
  170. logging.exception("获取元素文本值失败!")
  171. # 截图
  172. self.save_web_screenshot(img_doc)
  173. raise
  174.  
  175. # 鼠标悬浮操作
  176. def mouse_suspension(self,loc, img_doc):
  177. # 实例化ActionChains
  178. ac = ActionChains(self.driver)
  179. # 等待元素出现
  180. self.wait_eleVisible(loc, img_doc)
  181. # 查找元素
  182. ele = self.get_element(loc)
  183. # 鼠标悬浮
  184. try:
  185. ac.move_to_element(ele).perform()
  186. time.sleep(1)
  187. logging.info("鼠标悬浮成功!")
  188. except:
  189. # 日志
  190. logging.exception("鼠标悬浮失败!")
  191. # 截图
  192. self.save_web_screenshot(img_doc)
  193. raise
  194.  
  195. # 进入到iframe中
  196. def get_iframe(self,loc,img_doc):
  197. # 等待元素出现
  198. self.wait_eleVisible(loc, img_doc)
  199. # 查找元素
  200. ele = self.get_element(loc)
  201. # 进入iframe
  202. try:
  203. self.driver.switch_to.frame(ele)
  204. logging.info("进入iframe中成功!")
  205. except:
  206. # 日志
  207. logging.exception("进入到iframe中失败!")
  208. # 截图
  209. self.save_web_screenshot(img_doc)
  210. raise
  211.  
  212. # 通过文本选择下拉选择框
  213. def drop_down_select(self,loc,text,img_doc):
  214. # 等待元素出现
  215. self.wait_eleVisible(loc, img_doc)
  216. # 查找select元素
  217. ele = self.get_element(loc)
  218. # 下拉选择
  219. try:
  220. Select(ele.select_by_visible_text(text))
  221. logging.info("选择select成功!")
  222. except:
  223. # 日志
  224. logging.exception("下拉选择失败!")
  225. # 截图
  226. self.save_web_screenshot(img_doc)
  227. raise
  228.  
  229. # 选择非select的下拉选择框
  230. def drop_down_not_select(self,loc1,loc2,img_doc):
  231. # 先定位到下拉菜单
  232. # 等待元素出现
  233. self.wait_eleVisible(loc1, img_doc)
  234. # 查找下拉菜单元素
  235. self.click_element(loc1,"下拉菜单输入框")
  236. logging.info("查找下拉菜单输入框成功!")
  237. time.sleep(2)
  238. # 在对下拉菜单的选项进行选择
  239. try:
  240. # 选择下拉菜单选项
  241. # 等待元素出现
  242. self.wait_eleVisible(loc2, img_doc)
  243. self.click_element(loc2,"选择下拉菜单选项")
  244. logging.info("选择下拉菜单成功!")
  245. except:
  246. # 日志
  247. logging.exception("下拉选择失败!")
  248. # 截图
  249. self.save_web_screenshot(img_doc)
  250. raise
  251.  
  252. # 清空输入框中的内容
  253. def clear_data(self,loc,img_doc):
  254. # 等待元素出现
  255. self.wait_eleVisible(loc, img_doc)
  256. # 查找一个元素
  257. ele = self.get_element(loc)
  258. # 清空输入框
  259. try:
  260. ele.clear()
  261. logging.info("清空输入框成功!")
  262. except:
  263. # 日志
  264. logging.exception("清空输入框失败!")
  265. # 截图
  266. self.save_web_screenshot(img_doc)
  267. raise
  268.  
  269. # 上传操作(前提 :windows上传窗口已经出现。sleep1-2秒等待弹出的出现。)
  270. def upload(filePath, browser_type="chrome"):
  271. if browser_type == "chrome":
  272. title = "打开"
  273. else:
  274. title = ""
  275.  
  276. # 找元素
  277. # 一级窗口"#32770","打开"
  278. dialog = win32gui.FindWindow("#32770", title)
  279. ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) # 二级
  280. comboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, "ComboBox", None) # 三级
  281. # 编辑按钮
  282. edit = win32gui.FindWindowEx(comboBox, 0, 'Edit', None) # 四级
  283. # 打开按钮
  284. button = win32gui.FindWindowEx(dialog, 0, 'Button', "打开(&O)") # 四级
  285.  
  286. # 往编辑当中,输入文件路径.
  287. win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, filePath) # 发送文件路径
  288. win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 点击打开按钮

3.dir_config.py

dir_config.py模块里面封装的是项目当中需要用到的路径配置,该配置是相对项目来说的相对配置,这样项目无论放在哪里都能使用而不报错。

  1. # --^_^-- coding:utf-8 --^_^--
  2. # @Remark:路径配置
  3.  
  4. import os
  5.  
  6. # 框架项目顶层目录
  7. base_dir = os.path.split(os.path.split(os.path.abspath(__file__))[0])[0]
  8.  
  9. # 日志目录
  10. logs_dir = os.path.join(base_dir, "Outputs/logs")
  11.  
  12. # 截屏目录
  13. screenshot_dir = os.path.join(base_dir, "Outputs/screenshots")
  14.  
  15. # 测试数据目录
  16. testdatas_dir = os.path.join(base_dir, "TestDatas")
  17.  
  18. # 测试用例目录
  19. testcases_dir = os.path.join(base_dir, "TestCases")
  20.  
  21. # 测试报告目录
  22. htmlreport_dir = os.path.join(base_dir, "Outputs/reports")

4.HTMLTestRunnerNew.py

HTMLTestRunnerNew.py模块是用于生成HTML的测试报告模块。(具体的模块代码太长,不方便展示。有需要可私聊。)

5.logger.py

logger.py模块是自定义的log日志模块。

  1. # --^_^-- coding:utf-8 --^_^--
  2. # @Remark:日志模块
  3.  
  4. import logging
  5. from logging.handlers import TimedRotatingFileHandler
  6. import datetime
  7. from Common import dir_config
  8.  
  9. fmt = "%(asctime)s %(levelname)s %(filename)s %(funcName)s [ line:%(lineno)d ] %(message)s"
  10. datefmt = "%Y-%m-%d %H:%M:%S"
  11. # 获取当前时间
  12. now_time = datetime.datetime.now().strftime('%Y-%m-%d')
  13. # 把当前时间转换成str
  14. now_time_str = str(now_time)
  15.  
  16. handler_1 = logging.StreamHandler()
  17. handler_2 = TimedRotatingFileHandler(dir_config.logs_dir + "/" + now_time_str + "_Web.log", when='D', interval=10,backupCount=0, encoding='utf-8')
  18.  
  19. # 设置rootlogger 的输出内容形式,输出渠道
  20. logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO, handlers=[handler_1, handler_2])

Python+Selenium+Unittest实现PO模式web自动化框架(2)的更多相关文章

  1. Python+Selenium+Unittest实现PO模式web自动化框架(1)

    1.什么是PO模式? PO是Page Object的缩写 PO模式是自动化测试项目开发实践的最佳设计模式之一,讲页面定位和业务操作分开,也就是把对象的定位和测试脚本分开,从而提供可维护性. 主要有以下 ...

  2. Python+Selenium+Unittest实现PO模式web自动化框架(8)

    1.main.py模块的功能 最后就是要有一个项目入口,并且是需要加载测试用例集. # --^_^-- coding:utf-8 --^_^-- # @Remark:运行入口 "" ...

  3. Python+Selenium+Unittest实现PO模式web自动化框架(6)

    1.TestCases目录下的模块 TestCases目录下是存放测试用例的目录. TestCases目录下的测试用例采用unittest框架来构建. 例如:登录功能的测试用例.(test_1_log ...

  4. Python+Selenium+Unittest实现PO模式web自动化框架(4)

    1.PageLocators目录下的具体模块 2.PageLocators目录下主要放置个页面的元素定位.用于统一管理个页面的定位元素. 例如:登录页面的元素定位login_page_locator. ...

  5. Python+Selenium+Unittest实现PO模式web自动化框架(7)

    1.TestDatas目录的功能 TestDatas目录下存放的是测试数据,比如:登录功能的测试用例数据. # --^_^-- coding:utf-8 --^_^-- # @Remark:登录测试数 ...

  6. Python+Selenium+Unittest实现PO模式web自动化框架(5)

    1.PageObjects目录下的模块 该目录下是存放各页面功能点. 比如:login_page.py模块下就是存放登录页面上的各个功能点的.(登录功能.获取登录失败的提示信息) # --^_^-- ...

  7. Python+Selenium+Unittest实现PO模式web自动化框架(3)

    1.Outputs目录下的具体目录功能 2.logs目录 logs目录是用于存放log日志的一个目录. 2.reports目录 reports目录是用于存放测试报告的. 3.screenshots目录 ...

  8. python + selenium + unittest实现简单的UI自动化

    使用的版本是python 3,其中HTMLTestRunner是修改版本,参考以下博客并下载 https://blog.csdn.net/zhanin123/article/details/78950 ...

  9. 【转】基于Selenium的web自动化框架(python)

    1 什么是selenium Selenium 是一个基于浏览器的自动化工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.Sel ...

随机推荐

  1. C# HTML帮助类 包括补全标签 截取HTML字符串包含标签

    public static class HtmlHelper { /// <summary> /// 按文本内容长度截取HTML字符串(支持截取带HTML代码样式的字符串) /// < ...

  2. 编译nginx增加fair模块

    安装必要的软件 ubuntu里是 apt install wget gcc make zlib1g-dev libpcre3-dev 去官网下载最新稳定版的nginx源码 git clone 源码 g ...

  3. Azure Terraform(二)语法详解

    一,引言 上篇文章开始,我们简单介绍了以下通过基础设施管理工具----- Terraform,通过它来统一管理复杂的云基础设施资源.作为入门演示,使用Terraform 部署Azure 资源组的方式直 ...

  4. 看起来很唬人,然而却简单实用的CAP理论

    在做分布式系统开发时,经常会或多或少的听到CAP理论.或者是处理节点间数据一致性的问题.CAP理论很简单,但却是很多软件设计的宏观指导,因此也有人将之称为架构师必须掌握的理论之一.鉴于理论的东西相对来 ...

  5. [LeetCode]147. Insertion Sort List链表排序

    插入排序的基本思想 把排好的放在一个新的变量中,每次拿出新的,排进去 这个新的变量要有超前节点,因为第一个节点可能会有变动 public ListNode insertionSortList(List ...

  6. ServletContext的作用

    一个项目只有一个ServletContext对象,一个tomcat有多个项目 作用:在多核Servlet中来获取这个唯一的对象,使用ta给多个Servlet传递数据. 在Tomcat启动时创建,在To ...

  7. css 自定义悬浮窗写法

    HTML: css(sass): 复制代码 .info { } &:hover::after { content: attr(data-title); display: inline-bloc ...

  8. Java JVM——8.堆

    堆的核心概念 堆针对一个 JVM 进程来说是唯一的,也就是一个进程只有一个JVM,但是进程包含多个线程,他们是共享同一堆空间的. 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域. J ...

  9. ThreadLocal解决什么问题

    原创文章,转载请务必将下面这段话置于文章开头处(保留超链接).本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ ThreadLocal解决 ...

  10. 日常入坑1-Calendar类

    1.当前时间是一号的时候,通过计算上一天的日期的时候,需要注意了 Calendar calendar = Calendar.getInstance();calendar.set(2019,10,1); ...