1. 简介
今天分享和讲解的超神操作, 对于菜鸟来说是超神的操作, 对于大佬来说也就是几个简单方法的封装和调用. 这里讲解和分享这部分主要是为了培养小伙伴们和童鞋们的面向对象的开发思维, 对比这样做的好处让你自己身临其境的感受一番.
2. 自定义封装一个简单的 Log 类
本文介绍如何写一个 Python 日志类, 用来输出不同级别的日志信息到本地文件夹下的日志文件里. 为什么需要日志输出呢, 我们需要记录我们测试脚本到底做了什么事情, 最好的办法是写事件监听. 这个事件监听, 对我们现在来说, 还是有点复杂去理解, 所以我这里, 选择封装一个简单的日志类, 同样达到这个效果.
我们大概需要如下日志输出效果:
2.1 问题分析:
我们需要封装一个简单的日志类, 主要有以下内容:
1. 生成的日志文件格式是 年月日时分秒. log
2. 生成的 xxx.log 文件存储在项目根目录下 Logs 文件夹下
3. 这个日志类, 支持 INFO,ERROR 两种日志级别
4. 日志里, 每行日志输出, 如上图, 时间日期 + 执行类名称 + 日志级别 + 日志描述
2.2 解决问题思路:
1. 在根目录下新建一个 Logs 的文件夹, 如何获取这个 Log 的相对路径, 前面介绍过.
2. 日志的保存命名, 需要系统时间, 前面也介绍过时间格式化输出
3. Python 中有一个 logging 模块来支持我们自定义封装一个新日志类.
4. 在脚本里, 初始化一个日志类的实例对象, 然后去控制输出 INFO 还是 ERROR 日志信息.
自定义日志类封装如下: logger.py, 新建在 test 包下
2.3 代码实现:
2.4 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- import logging
- import os.path
- import time
- class Logger(object):
- def __init__(self, logger):
- """
- 指定保存日志的文件路径, 日志级别, 以及调用文件
- 将日志存入到指定的文件中
- :param logger:
- """
- # 创建一个 logger
- self.logger = logging.getLogger(logger)
- self.logger.setLevel(logging.DEBUG)
- # 创建一个 handler, 用于写入日志文件
- rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
- print(os.getcwd())
- log_path = (os.path.dirname(os.getcwd() + '\\Logs\\'))
- print(log_path)
- log_name = log_path + rq + '.log'
- fh = logging.FileHandler(log_name)
- fh.setLevel(logging.INFO)
- # 再创建一个 handler, 用于输出到控制台
- ch = logging.StreamHandler()
- ch.setLevel(logging.INFO)
- # 定义 handler 的输出格式
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- fh.setFormatter(formatter)
- ch.setFormatter(formatter)
- # 给 logger 添加 handler
- self.logger.addHandler(fh)
- self.logger.addHandler(ch)
- def getlog(self):
- return self.logger
2.5 新建日志测试类
新写一个测试日志类, 相关代码如下:
2.5.1 代码实现:
2.5.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- from test1.logger import Logger
- mylogger = Logger(logger='test_log').getlog()
- class TestMyLog(object):
- def print_log(self):
- driver = webdriver.Chrome()
- mylogger.info("打开浏览器")
- driver.maximize_window()
- mylogger.info("最大化浏览器窗口.")
- driver.implicitly_wait(8)
- driver.get("https://www.baidu.com")
- mylogger.info("打开百度首页.")
- time.sleep(1)
- mylogger.info("暂停一秒.")
- driver.quit()
- mylogger.info("关闭并退出浏览器.")
- testlog = TestMyLog()
- testlog.print_log()
2.5.3 运行结果:
运行代码后, 控制台打印如下图的结果
2.5.4 文件保存结果:
运行代码后, 在 Logs 文件夹下可以看到日志文件, 如下图的结果
在 PyCharm 里运行下这个测试类, 会在根目录下的 Logs 文件下, 新建一个日志文件, 打开效果如文章开头的日志输出图. 好了, 关于自定义封装 log 类, 自己好好去读下代码, 理解下每行代码的意思, 日志类的封装和调用就介绍到这里.
3. 把截图类方法封装到前面的 BasePage.py
本文介绍把截图类方法封装到 BasePage.py 文件里, 这个文件是在前面 Selenium 方法二次封装文章里创建的, 具体代码请到前面这篇里找. 我们截图类写死了把截图图片保存到根目录下的 Screenshots 文件夹里, 图片名称是当前系统时间, 图片后缀名是 PNG.
新的 BasePage.py 内容如下:
3.1 代码实现:
3.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- import os
- import time
- from test1.logger import Logger
- mylog = Logger(logger='BasePage').getlog()
- class BasePage(object):
- """
- 主要是把常用的几个 Selenium 方法封装到 BasePage 这个类, 我们这里演示以下几个方法
- back()
- forward()
- get()
- quit()
- """
- def __init__(self, driver):
- """
- 写一个构造函数, 有一个参数 driver
- :param driver:
- """
- self.driver = driver
- def back(self):
- """
- 浏览器后退按钮
- :param none:
- """
- self.driver.back()
- def forward(self):
- """
- 浏览器前进按钮
- :param none:
- """
- self.driver.forward()
- def open_url(self, url):
- """
- 打开 url 站点
- :param url:
- """
- self.driver.get(url)
- def quit_browser(self):
- """
- 关闭并停止浏览器服务
- :param none:
- """
- self.driver.quit()
- def take_screenshot(self):
- """
- 截图并保存在根目录下的 Screenshots 文件夹下
- :param none:
- """ file_path = os.path.dirname(os.getcwd()) +'/Screenshots/' rq = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
- screen_name = file_path + rq + '.png'
- try :
- self.driver.get_screenshot_as_file(screen_name)
- mylog.info("开始截图并保存")
- except Exception as e:
- mylog.error("出现异常",format(e))
3.3 新建截图类
主要看最后一个截图类方法的封装.
测试类相关代码如下:
3.3.1 代码实现:
3.3.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- import time
- from selenium import webdriver
- from blog.basepage import BasePage
- class TestScreenshot(object):
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.implicitly_wait(10)
- basepage = BasePage(driver)
- def test_take_screen(self):
- self.basepage.open_url("https://www.baidu.com")
- time.sleep(1)
- self.basepage.take_screenshot()
- self.basepage.quit_browser()
- test = TestScreenshot()
- test.test_take_screen()
3.3.3 运行结果:
运行代码后, 控制台打印如下图的结果
3.3.4 截图保存结果:
运行代码后, 在 Screenshots 文件夹下可以看到截图文件, 如下图的结果
运行后, 可以在根目录下 Screenshots 文件夹里找到百度首页截图.
本文就介绍了截图类方法添加到 BasePage 里, 介绍了如何保存到根目录下的 Screenshots 文件夹.
4. Python 中的继承的使用
本文开始介绍一个面向对象设计领域里, 很常见的一种思想, 继承. 继承有很多好处, 常听到的一句话就是, 子类能够直接使用父类的方法, 这样就可以减少子类代码量. 其实, 在自动化测试框架设计过程中, 是很有必要把继承加入到你的测试脚本中去. 接下来我们, 简单写一个 Python 文件, 来演示下继承的基本使用.
4.1 新建 classA.py
1. 在 test1 包名下新建一个 classA.py, 这个就是我们的父类, 里面有一个打开 Chrome 浏览器和打开百度首页的方法.
4.1.2 代码实现:
4.1.3 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- from selenium import webdriver
- import time
- class ClassA(object):
- def open_baidu(self):
- driver = webdriver.Chrome()
- driver.maximize_window()
- driver.get("https://www.baidu.com")
- time.sleep(1)
- driver.quit()
4.2 新建 classB.py
1. 在 test2 包下新建一个 classB.py 文件, 这个继承 classA.py 里的 ClassA 类.
4.2.1 代码实现:
4.2.2 参考代码:
- # coding=utf-8
- # 1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- # 2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-12-16
- @author: 北京 - 宏哥 QQ 交流群: 705269076
- Project: 《手把手教你》系列进阶篇之 4-python+ selenium 自动化测试 - python 基础扫盲
- '''
- # 3. 导入模块
- from test1.classA import ClassA
- class ClassB(ClassA):
- def test_inherit(self):
- self.open_baidu()
- test = ClassB()
- test.test_inherit()
4.2.3 运行结果:
运行代码后, 控制台打印如下图的结果
通过上面可以看出, 只需要一句代码就可以实现 ClassA 中的方法, 这个就是继承的好处, 减少了很多代码的书写, 提高代码的复用. 在定义 ClassB 的时候就要指明 ClassB 的父类是 ClassA. 继承相关的话题就介绍到这里, 将在后面自动化框架设计会再次提到.
5. 小结
5.1 中文乱码
遇到的问题: 细心地小伙伴或者同学们会发现在日志文件中的内容或出现中文乱码, 如下图示:
解决办法: 在 FileHandler 此处要设置 encoding 格式,
fh = logging.FileHandler(log_name,encoding='utf-8')
修改后, 运行代码日志文件内容如下图所示:
5.2 路径问题
因为宏哥在代码实践的过程中这部分遇到小问题, 就是日志文件和截图放不在指定的文件夹下, 所以这里拿出来单独说一下.
- # 创建一个 handler, 用于写入日志文件
- rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
- #当前目录
- print(os.getcwd())
- #根目录
- print(os.path.dirname(os.getcwd()))
- #log_path = (os.path.dirname(os.getcwd())+ '\\Logs\\')
- log_path = os.getcwd() + '\\Logs\\'
- print(log_path)
代码说明:
os.getcwd() : 获取的当前最外层调用的脚本路径, 即 getPath 所在的目录也可描述为起始的执行目录, A 调用 B, 起始的是 A, 那么获取的就是 A 所在的目录路径.
os.path.dirname(): 去掉脚本的文件名, 返回目录.
好了, 今天的分享就到这里吧!!! 谢谢各位的耐心阅读.
您的肯定就是我进步的动力. 如果你感觉还不错, 就请鼓励一下吧! 记得随手点波 推荐不要忘记哦!!!
别忘了点推荐留下您来过痕迹
来源: https://www.cnblogs.com/du-hong/p/12034859.html