问题:
在进行UI自动化时,想要输出每次查找元素的日志,引入logging模块,并设置logging.INFO,但是实际上运行正常,但控制台并没有输出日志:
class BasePage:
_driver = None
_params={}
_base_url = ""
logging.basicConfig(level=logging.INFO)
def __init__(self,driver:WebDriver = None):
if driver is None:
chrome_options = Options()
chrome_options.debugger_address = "127.0.0.1:9222"
self._driver = webdriver.Chrome(options=chrome_options)
self._driver.maximize_window()
self._driver.implicitly_wait(3)
else:
self._driver = driver
if self._base_url != "":
self._driver.get(self._base_url)
@handlie_blacklist
def find(self,by,locator):
logging.info(f"find:{locator}")
if by == None:
result=self._driver.find_element(*locator)
else:
result = self._driver.find_element(by,locator)
return result
解决思路:
反复检查这段代码无误后,只能深入 logging.basicConfig
函数看看这个 python 自带的日志配置函数究竟做了什么(截取一部分)
def basicConfig(**kwargs):
_acquireLock()
try:
if len(root.handlers) == 0:
handlers = kwargs.pop("handlers", None)
if handlers is None:
if "stream" in kwargs and "filename" in kwargs:
raise ValueError("'stream' and 'filename' should not be "
"specified together")
else:
if "stream" in kwargs or "filename" in kwargs:
raise ValueError("'stream' or 'filename' should not be "
"specified together with 'handlers'")
if handlers is None:
filename = kwargs.pop("filename", None)
mode = kwargs.pop("filemode", 'a')
if filename:
h = FileHandler(filename, mode)
else:
stream = kwargs.pop("stream", None)
h = StreamHandler(stream)
handlers = [h]
dfs = kwargs.pop("datefmt", None)
style = kwargs.pop("style", '%')
if style not in _STYLES:
raise ValueError('Style must be one of: %s' % ','.join(
_STYLES.keys()))
fs = kwargs.pop("format", _STYLES[style][1])
fmt = Formatter(fs, dfs, style)
for h in handlers:
if h.formatter is None:
h.setFormatter(fmt)
root.addHandler(h)
分析这段程序,有个if
语句判断 root.handlers
为空,则会运行后续代码给将每个 handler 添加到根 logger 的逻辑。推测root.handlers 不为空。
看下这个函数basicConfig()
说明部分
Do basic configuration for the logging system.
This function does nothing if the root logger already has handlers
configured. It is a convenience method intended for use by simple scripts
to do one-shot configuration of the logging package.
The default behaviour is to create a StreamHandler which writes to
sys.stderr, set a formatter using the BASIC_FORMAT format string, and
add the handler to the root logger.
A number of optional keyword arguments may be specified, which can alter
the default behaviour.
渣道翻译:
对日志系统进行基本配置。
如果根日志记录器已经有处理程序,则此函数不执行任何操作配置。它是一种便于简单脚本使用的方法对日志包进行一次性配置。
默认行为是创建一个写入的StreamHandler。使用BASIC_FORMAT格式字符串设置格式化程序,以及将处理程序添加到根日志记录器。
可以指定许多可选关键字参数,这些参数可以更改默认的行为。
即在图1代码调用logging.basicConfig
前已经调用了一次basicConfig
,导致设置失效,其实还是使用系统默认的日志文件,根记录器始终默认为警告级别
。
打个断点验证下:
说明:
在调用logging.basicConfig
前打印了root处理器的handles是有两个的,但是进一步去追踪是哪个地方先行调用了basicConfig
,目前我还没有头绪,若有方法,望告知。
解决:
在logging.basicConfig
前清理已有 handlers
root_logger = logging.getLogger()
for h in root_logger.handlers[:]:
root_logger.removeHandler(h)
logging.basicConfig(level=logging.INFO)
注意:不要写成for h in root_logger.handlers:
再次执行代码,控制台就正常输出日志了,完事收工!
参考帖子:
追踪方法很好:python logging 模块配置咋不起作用了?
其他logging相关知识:
python中logging日志模块详解
Python日志输出——logging模块
干货:
Python中内置的日志模块logging用法详解
python logging 替代print 输出内容到控制台和重定向到文件
# log.Log_Info('nihaohaohao')
# 设置log的存储文件
logging.basicConfig(filename = os.path.join(os.getcwd(), 'logs/report_log.txt'), level = logging.DEBUG)
logging.info('可以了吗嗷嗷嗷!')
原来是在调用logging.basicConfi
2.代码实例
import logging
'''format=%(asctime)s具体时间 %(filename)s文件名 %(lenvelname)s日志等级 %(message)s具体信息
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s %(levelname)s %(message)s',
说到日志,无论是开发写代码还是写UI自动化测试,都离不开日志的记录,它能给我们在定位问题、缺陷时带来很大的方便。通常测试人员使用最多的方法就是用print来打印出日志和报错信息,但是对于一些项目比较大的项目,使用print就不是那么方便了。因为print打印出来的日志没有时间,不知道日志记录的位置,针对这种情况,我们可以使用python自带的logging模块,可以很好地解决上面问题。...
logging 模块是 Python 内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比 print,具备如下优点:
可以通过设置不同的日志等级,在 release 版本中只输出重要信息,而不必显示大量的调试信息;
print 将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging
则可以由开发者决定将信息输出到什么地方,以及怎么输出;
和 print 相比,logging 是线程安全的。
参考文献:参考文章
生成文件名与指定日志
在这个示例中,我们将日志级别设置为 INFO,表示只记录 INFO 级别及以上的日志信息,输出格式设置为 %(asctime)s %(levelname)s %(message)s,表示在每条日志记录中包括时间戳、日志级别和日志消息。除了 basicConfig 方法,logging 模块还提供了很多其他的配置和使用方法,例如可以将日志输出到文件中,可以在日志记录中包含调用栈信息等。在这个示例中,我们使用 basicConfig 方法设置了日志级别为 DEBUG,并记录了不同级别的日志信息。
logging.info('info')
logging.warning('出错了')
logging.error('error message') logging.critical('critical message')
默认日志级别设置为WARNING...
logging.basicConfig(level=logging.INFO,
format='levelname:%(levelname)s filename: %(filename)s '
'outputNumber:...
# 日志信息配置
logging.basicConfig(level=logging.INFO, # 输出到日志文件中的日志级别
filename='mylog.log', # 日志文件名称
为什么要用logging模块在实际应用中,日志文件十分重要,通过日志文件,我们知道程序运行的细节;同时,当程序出问题时,我们也可以通过日志快速定位问题所在。在我们写程序时,也可以借助logging模块的输出信息来调试代码。但是很多人还是在程序中使用print()函数来输出一些信息,比如:print 这样用的话缺点很明显,当程序写好运行时,我们要把这些print()函数删掉,在简单的的程序中用还行,...
橙好科技logging模块教程
文章目录1-logging介绍2-日志作用3-日志配置basicConfig3-日志级别level4-日志格式format4-输出日志到控制台5-输出日志到文件6-输出日志到控制台和文件7-骚操作
1-logging介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvNqUq0s-1620