python自动化测试日志收集logging

2021-08-26 14:56发布

日志无论是在测试、开发中都非常重要,如果你在跑自动化时程序报错了,但是你没有日志你怎么去定位时程序错误还是你app的错误?或者还是其它环境因素?

 

试想我们运行自动化测试用例时,要保存一份日志,最重要的是什么呢?

首先,我们得知道日志保存的位置;其次,日志的级别是什么,这决定了日志的详细程度;还有最重要的,你的日志应该是什么格式的?这包含了日志生成的时间,日志对应的代码的行数,日志详细信息等。

 

日志级别

脚本运行会有很多的情况,比如调试信息、报错异常信息等。日志要根据这些不同的情况来继续分级管理,不然对于排查问题的筛选会有比较大的干扰。日志一般定位的级别如下:

级别

何时使用

DEBUG

调试信息,也是最详细的日志信息。

INFO

证明事情按预期工作。

WARNING

表明发生了一些意外,或者不久的将来会发生问题(如‘磁盘满了’)。软件还是在正常工作。

ERROR

由于更严重的问题,软件已不能执行一些功能了。

CRITICAL

严重错误,表明软件已不能继续运行了。

首先我们日志需要按照info、debug、error等级别来进行区分的。当然这个级别可以自己去设置。在一般的情况下我们普通的输出我们直接用info类型,调试的时候用debug类型,如果预计有错误时那么我们就需要用error类型的日志,一般情况去info级别最为合适。

 

日志格式

日志格式化是为了提高日志的可阅读性,比如:时间+模块+行数+日志具体信息的内容格式。

    [formatter_form01]            
    format=%(asctime)s %(filename)s [line:%(lineno)d]  %(levelname)s  %(message)s
    datefmt=%Y-%m-%d %H:%M:%S

日志效果如下

2021-08-26 14:09:19 testmycase.py [line:9] INFO info类型的日志

2021-08-26 14:09:19 testmycase.py [line:10] ERROR error 的日志


Logging模块的使用如下:

import 
logging
import 
logging.config
#这个是配置文件的路径
CONF_LOG = "log.conf"
logging.config.fileConfig(CONF_LOG)
logger = logging.getLogger('testmycase.py')

#下面就是使用日志打印日志信息
logger.info("info类型的日志")
logger.error("error 的日志")


    其中log.conf是日志的配置文件,其中设置一些日志的基本信息,日志配置信息如下:

[loggers]
keys=root,infoLogger,errorlogger
[logger_root]
level=DEBUG
handlers=infohandler,errorhandler
[logger_infoLogger]
handlers=infohandler
qualname=infoLogger
propagate=0
[logger_errorlogger]
handlers=errorhandler
qualname=errorlogger
propagate=0
####################################
[handlers]
keys=infohandler,errorhandler
[handler_infohandler]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stdout,)
[handler_errorhandler]
class=FileHandler
level=ERROR
formatter=form01
args=('./mylog.log', 'a')
#####################################
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s [line:%(lineno)d]  %(levelname)s  %(message)s
datefmt=%Y-%m-%d %H:%M:%S
[formatter_form02]
format=%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S

    每个人可能根据自己实际需求配置不同,但是基本如上,再根据自己的需求微调。

    配置信息的基本释义如下

    1. 初始化 logger = logging.getLogger("endlesscode"),getLogger()方法后面最好加上所要日志记录的模块名字,后面的日志格式中的%(name)s 对应的是这里的模块名字

    2. 设置级别 logger.setLevel(logging.DEBUG),Logging中有NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL这几种级别,日志会记录设置级别以上的日志

    3. Handler,常用的是StreamHandler和FileHandler,windows下你可以简单理解为一个是console和文件日志,一个打印在CMD窗口上,一个记录在一个文件上

    4. formatter,定义了最终log信息的顺序,结构和内容,我喜欢用这样的格式 '[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S',

  %(name)s Logger的名字

    %(levelname)s 文本形式的日志级别

    %(message)s 用户输出的消息

    %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

    %(levelno)s 数字形式的日志级别

    %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有

    %(filename)s 调用日志输出函数的模块的文件名

    %(module)s  调用日志输出函数的模块名

    %(funcName)s 调用日志输出函数的函数名

    %(lineno)d 调用日志输出函数的语句所在的代码行

    %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示

    %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数

    %(thread)d 线程ID。可能没有

    %(threadName)s 线程名。可能没有

    %(process)d 进程ID。可能没有


    下面我们根据考研帮的一个案例来实操一下:

    测试场景为:启动考研帮App的脚本增加log采集功能,设置指定的日志格式输出,并将日志保存到指定文件。

 

    首先需要编写如上的log.conf的日志文件配置

    然后编写考研启动的.py文件,代码如下

    在考研帮的.py中除了对考研帮基本的测试外,加入日志收集的代码如下

import 
logging
import 
logging.config
#这个是配置文件的路径
CONF_LOG = "log.conf"
logging.config.fileConfig(CONF_LOG)
logger = logging.getLogger('testmycase.py')

    在考研帮代码中的某个节点可以加入日志信息,如检查跳过按钮可以写loging.info("check skip")

    整体代码如下

"""Created on 2021-0826
@author:米丫"""

from appium import webdriver
from time import sleep
caps={}
caps["platformName"] = "Android"
caps["platformVersion"] = "4.4.2"
caps["deviceName"] = "127.0.0.1:62001"
caps["appPackage"] = "com.tal.kaoyan"
caps["appActivity"] = "com.tal.kaoyan.ui.activity.SplashActivity"
caps["noReset"] = True
 
driver=webdriver.Remote('http://localhost:4723/wd/hub',caps)
sleep(2)
 
def login():
    loging.info("check login")
    #输入账号
    el3 = driver.find_element_by_id("com.tal.kaoyan:id/login_email_edittext")
    el3.send_keys("zgjy1234")
    sleep(2)
    #输入密码
    el4 = driver.find_element_by_id("com.tal.kaoyan:id/login_password_edittext")
    el4.send_keys("zgjy123456")
    sleep(2)
    #点击登录
    el5 = driver.find_element_by_id("com.tal.kaoyan:id/login_login_btn")
    el5.click()
    sleep(2)
 
try:
    loging.info("check update")
    #取消升级
    el1=driver.find_element_by_id("android:id/button2")
except Exception:
    login()
else:
    el1.click()
    sleep(2)
 
 
try:
    loging.info("check skip")
    #跳过
    el2 = driver.find_element_by_id("com.tal.kaoyan:id/tv_skip")
except Exception:
    login()
else:
    el2.click()
    sleep(2)
    login()
 
sleep(2)
driver.quit()


    最终运行代码日志信息其中一条如下

    2021-08-26 14:22:19 testmycase.py [line:41] INFO check update

    至此,我们在实现考研帮的启动的同时完成了日志的收集,并且日志配置文件,可以适用于很多模块,很多app甚至是web的使用中,这种日志收集的方式可谓是适用性非常地广泛。