在上一节的自动化测试框架搭建-【配置】的基础上为框架加上日志log,既然用到了log类,可以学习Python-logging进行学习,在utils中创建一个log.py文件,Python有很方便的logging库,对其进行简单的封装,使框架可以很简单地打印日志(输出到控制台以及日志文件)。
对于logger模块,有几篇自己在学习过程中觉得可以值得学习的博客:Python logging模块详解和logger模块详解;值得学习和借鉴。
#coding:utf-8
'''log.py output the log'''
import logging
from logging.handlers import TimedRotatingFileHandler
from Framework.utils.config import LOG_PATH
class Logger():
def __init__(self,logger_name = 'framework'):
#创建一个logger实例,如果参数为空则返回root logger
self.logger = logging.getLogger(logger_name)
logging.root.setLevel(logging.NOTSET)
self.log_file_name = 'test.log'
self.backup_count = 5
#日志输出级别
self.console_output_level = 'WARNING'
self.file_output_level = 'DEBUG'
#日志输出格式
self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
def get_logger(self):
'''在logger日志中添加日志句柄并返回,如果logger句柄已经存在,则直接返回'''
if not self.logger.handlers:
console_handler = logging.StreamHandler()
console_handler.setFormatter(self.formatter)
console_handler.setLevel(self.console_output_level)
self.logger.addHandler(console_handler)
#每天重新创建一个日志文件,最多保留backup_count份
file_handler = TimedRotatingFileHandler(filename=LOG_PATH + self.log_file_name,
when='D',
interval=1,
backupCount=self.backup_count,
delay=True,
encoding='utf-8'
)
file_handler.setFormatter(self.formatter)
file_handler.setLevel(self.file_output_level)
self.logger.addHandler(file_handler)
return self.logger
logger = Logger().get_logger()
if __name__ == '__main__':
print logger
修改test_baidu3.py模块,将输出日志功能加入到方法中,同时为了使用类方法实现测试方法的共享测试数据初始化和回收工作,从而使用@classmethod只需要初始化一次测试环境并且在测试用例执行完成后进行环境恢复。
#coding:utf-8
'''test_baidu3 This moudle has a logger function'''
import time
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from Framework.utils.config import Config,DRIVER_PATH
from Framework.utils.log1 import logger
class TestBaiDu(unittest.TestCase):
URL = Config().get('URL')
locator_kw = (By.ID, 'kw')
locator_su = (By.ID, 'su')
locator_result = (By.XPATH, '//div[contains(@class, "result")]/h3/a')
@classmethod
#def setUp(self):
def setUp(cls):
cls.driver = webdriver.Chrome(executable_path=DRIVER_PATH + '\chromedriver.exe')
cls.driver.get(cls.URL)
@classmethod
#def tearDown(self):
def tearDown(cls):
cls.driver.quit()
def test_search_0(self):
self.driver.find_element(*self.locator_kw).send_keys('selenium')
self.driver.find_element(*self.locator_su).click()
time.sleep(2)
links = self.driver.find_elements(*self.locator_result)
for link in links:
#print(link.text)
logger.info(link.text)
def test_search_1(self):
self.driver.find_element(*self.locator_kw).send_keys('Python selenium')
self.driver.find_element(*self.locator_su).click()
time.sleep(2)
links = self.driver.find_elements(*self.locator_result)
for link in links:
#print(link.text)
logger.info(link.text)
if __name__ == '__main__':
unittest.main()
在工程Framework下生成了一个logtest.log日志,输出结果:
之后,由于log.py模块中有很多设置,将其放置到config.yaml中
URL: http://www.baidu.com
log:
file_name: test.log
backup: 5
console_level: WARNING
file_level: DEBUG
pattern: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
同时修改log1.py,读取config,如果config中有,则采用文件中的设置,否则,采用默认设置
#coding:utf-8
'''log1.py output the log'''
"""
日志类。通过读取配置文件,定义日志级别、日志文件名、日志格式等。
一般直接把logger import进去
from utils.log import logger
logger.info('test log')
"""
import logging
from logging.handlers import TimedRotatingFileHandler
from Framework.utils.config import LOG_PATH,Config
class Logger():
def __init__(self,logger_name = 'framework'):
#创建一个logger实例,如果参数为空则返回root logger
self.logger = logging.getLogger(logger_name)
logging.root.setLevel(logging.NOTSET)
c = Config().get('log')
self.log_file_name = c.get('file_name') if c and c.get('file_name') \
else 'test.log' #日志文件
self.backup_count = c.get('backup') if c and c.get('backup') else 5 # 保留的日志数量
#日志输出级别
self.console_output_level = c.get('console_level') if c and \
c.get('console_level') else 'WARNING'
self.file_output_level = c.get('file_level') if c and c.get('file_level') else 'DEBUG'
# 日志输出格式
pattern = c.get('pattern') if c and c.get('pattern') \
else '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
self.formatter = logging.Formatter(pattern)
def get_logger(self):
"""在logger中添加日志句柄并返回,如果logger已有句柄,则直接返回
我们这里添加两个句柄,一个输出日志到控制台,另一个输出到日志文件。
两个句柄的日志级别不同,在配置文件中可设置。
"""
if not self.logger.handlers:
console_handler = logging.StreamHandler()
console_handler.setFormatter(self.formatter)
console_handler.setLevel(self.console_output_level)
self.logger.addHandler(console_handler)
#每天重新创建一个日志文件,最多保留backup_count份
file_handler = TimedRotatingFileHandler(filename=LOG_PATH + self.log_file_name,
when='D',
interval=1,
backupCount=self.backup_count,
delay=True,
encoding='utf-8'
)
file_handler.setFormatter(self.formatter)
file_handler.setLevel(self.file_output_level)
self.logger.addHandler(file_handler)
return self.logger
logger = Logger().get_logger()
if __name__ == '__main__':
print logger
由于这里的日志模块为log1.py,因此在test_baidu3.py做如下修改
from Framework.utils.log1 import logger