一旋膳、logging模塊日志級別介紹
日志等級一共分成5個,從低到高分別是:
- DEBUG:輸出詳細的運行情況擅羞,主要用于測試
- INFO:確認一切按預期運行减俏,一般用于輸出重要運行情況
- WARNING:一些預料不到的事情發(fā)生了,但軟件還能按預期工作奏夫,在不久的將來會出現問題
- ERROR:發(fā)生了錯誤历筝,軟件沒能執(zhí)行某功能梳猪,但軟件可以繼續(xù)運行
- CRITICAL:發(fā)生了嚴重的錯誤,程序本身可能無法繼續(xù)運行
5個等級分別對應5種打印日志的方法:debug呛哟、info扫责、warning逃呼、error抡笼、critical
二、日志收集器
設置日志收集器的名字和日志收集等級。
- 設置日志收集器的名字:使用logging模塊中getLogger方法設置日志名字拾碌。
- 設置日志等級:使用logging模塊中setLevel方法設置日志等級校翔,等級名稱一定要大寫
1.不設置日志收集器名字和日志收集等級灾前,日志輸出等級默認是WARNING及以上
import logging
# 一
# 日志默認收集等級為:warning及以上(warning、error饲嗽、critical)
a = 100
print("調試數據", a)
logging.debug("這個是logging模塊的調試信息a: {}".format(a))
logging.info("這個是logging模塊的調試信息")
logging.warning("這個是logging模塊的調試信息")
logging.error("這個是logging模塊的調試信息")
logging.critical("這個是logging模塊的調試信息")
輸出結果如下:
調試數據 100
WARNING:root:這個是logging模塊的調試信息
ERROR:root:這個是logging模塊的調試信息
CRITICAL:root:這個是logging模塊的調試信息
2.不設置日志收集器名字的情況下貌虾,設置日志收集等級裙犹,日志輸出等級跟日志收集等級一致
import logging
# 二
# 不設置日志收集器名字叶圃,默認使用root
# 不設置日志收集器名字的情況下,設置日志收集等級沉馆,日志輸出等級跟日志收集等級一致
log_lev = logging.getLogger()
log_lev.setLevel("DEBUG")
a = 100
print("調試數據", a)
logging.debug("這個是logging模塊的調試信息a: {}".format(a))
logging.info("這個是logging模塊的調試信息")
logging.warning("這個是logging模塊的調試信息")
logging.error("這個是logging模塊的調試信息")
logging.critical("這個是logging模塊的調試信息")
輸出結果如下:
調試數據 100
DEBUG:root:這個是logging模塊的調試信息a: 100
INFO:root:這個是logging模塊的調試信息
WARNING:root:這個是logging模塊的調試信息
ERROR:root:這個是logging模塊的調試信息
CRITICAL:root:這個是logging模塊的調試信息
3.只設置日志收集器名字和日志收集等級悍及,不設置日志的輸出心赶,有一個默認日志輸出等級,日志輸出等級為warning以上
import logging
# 三
# 日志的收集
# 設置日志收集器缨叫,設置日志收集等級
log_lev = logging.getLogger("my_log")
log_lev.setLevel("DEBUG")
# 日志的輸出(只設置日志收集器名字和日志收集等級荔燎,不設置日志的輸出有咨,有一個默認日志輸出等級,日志輸出等級等級為warning以上)
a = 100
print("調試數據", a)
log_lev.debug("這個是logging模塊的debug信息a: {}".format(a))
log_lev.info("這個是logging模塊的info信息")
log_lev.warning("這個是logging模塊的warning信息")
log_lev.error("這個是logging模塊的error信息")
log_lev.critical("這個是logging模塊的critical信息")
輸出結果如下:
調試數據 100
這個是logging模塊的warning信息
這個是logging模塊的error信息
這個是logging模塊的critical信息
三、日志輸出渠道
通過設置日志收集器名字和日志收集等級來收集不同等級的日志渣叛,最后設置日志輸出渠道來輸出不同等級的日志淳衙。
- 創(chuàng)建日志輸出通道。
- 設置日志輸出渠道等級肠牲,等級名稱全部要大寫埂材。
- 將日志輸出渠道添加到日志收集器中
1.日志輸出到控制臺的渠道
import logging
# 四
# 日志的收集
# 設置日志收集器俏险,設置日志收集等級
log_lev = logging.getLogger("my_log")
log_lev.setLevel("DEBUG")
# # 日志的輸出(只設置日志的收集,不設置日志的輸出裤唠,有一個默認日志輸出通道莹痢,日志輸出通道等級為warning以上)
# 創(chuàng)建日志輸出通道竞膳,設置日志輸出通道等級
sh = logging.StreamHandler()
sh.setLevel("DEBUG")
# 將輸出渠道添加到日志收集器
log_lev.addHandler(sh)
a = 100
print("調試數據", a)
log_lev.debug("-------------這個是logging模塊的debug信息a: {}".format(a))
log_lev.info("這個是logging模塊的info信息")
log_lev.warning("這個是logging模塊的warning信息")
log_lev.error("這個是logging模塊的error信息")
log_lev.critical("這個是logging模塊的critical信息")
輸出結果如下:
調試數據 100
-------------這個是logging模塊的debug信息a: 100
這個是logging模塊的info信息
這個是logging模塊的warning信息
這個是logging模塊的error信息
這個是logging模塊的critical信息
2.日志輸出到文件的渠道
import logging
# 五
# 日志的收集
# 設置日志收集器坦辟,設置日志收集等級
log_lev = logging.getLogger("my_log_2")
log_lev.setLevel("DEBUG")
# 日志輸出
# 設置日志輸出渠道锉走,設置日志輸出渠道等級
sh = logging.StreamHandler()
sh.setLevel("DEBUG")
# 將輸出渠道添加到日志收集器
log_lev.addHandler(sh)
# 設置日志輸出到文件的渠道,設置日志輸出渠道等級
fh = logging.FileHandler(filename="test.log",encoding="utf8")
fh.setLevel("DEBUG")
# 將輸出渠道添加到日志收集器
log_lev.addHandler(fh)
a = 100
print("調試數據", a)
log_lev.debug("-------------這個是logging模塊的debug信息a: {}".format(a))
log_lev.info("這個是logging模塊的info信息")
log_lev.warning("這個是logging模塊的warning信息")
log_lev.error("這個是logging模塊的error信息")
log_lev.critical("這個是logging模塊的critical信息")
輸出結果如下:
- 控制臺輸出結果
調試數據 100
-------------這個是logging模塊的debug信息a: 100
這個是logging模塊的info信息
這個是logging模塊的warning信息
這個是logging模塊的error信息
這個是logging模塊的critical信息
- 文件內容
-------------這個是logging模塊的debug信息a: 100
這個是logging模塊的info信息
這個是logging模塊的warning信息
這個是logging模塊的error信息
這個是logging模塊的critical信息
四挪蹭、日志輸出格式
- 寫明日志格式梁厉,用一個字符串代替或者直接在函數中寫明格式。
- 通過logging模塊的Formatter方法設置日志格式
- 將日志輸出渠道中的日志格式設置為上述日志格式
import logging
# 設置日志收集器只冻,設置日志收集器等級
my_log = logging.getLogger("my_log")
my_log.setLevel("DEBUG")
# 設置日志輸出格式
str_form = "%(asctime)s - [%(filename)s - line%(lineno)d] - %(name)s - %(levelname)s: %(message)s"
formater = logging.Formatter(str_form)
# 設置日志輸出渠道,設置日志輸出渠道等級
sh = logging.StreamHandler()
sh.setLevel("DEBUG")
sh.setFormatter(formater)
# 將輸出渠道添加到日志收集器中
my_log.addHandler(sh)
# 設置日志輸出到文件的渠道,設置日志輸出渠道等級
fh = logging.FileHandler(filename="test.log", encoding="utf8")
fh.setLevel("INFO")
fh.setFormatter(formater)
# 將輸出到文件渠道添加到日志收集器中
my_log.addHandler(fh)
a = 100
print("調試數據", a)
my_log.debug("這個是logging模塊的debug信息a: {}".format(a))
my_log.info("這個是logging模塊的info信息")
my_log.warning("這個是logging模塊的warning信息")
my_log.error("這個是logging模塊的error信息")
my_log.critical("這個是logging模塊的critical信息")
輸出結果如下:
2019-11-05 15:35:39,462 - [test_1029_log_format.py - line36] - my_log - DEBUG: 這個是logging模塊的debug信息a: 100
調試數據 100
2019-11-05 15:35:39,462 - [test_1029_log_format.py - line37] - my_log - INFO: 這個是logging模塊的info信息
2019-11-05 15:35:39,463 - [test_1029_log_format.py - line38] - my_log - WARNING: 這個是logging模塊的warning信息
2019-11-05 15:35:39,463 - [test_1029_log_format.py - line39] - my_log - ERROR: 這個是logging模塊的error信息
2019-11-05 15:35:39,463 - [test_1029_log_format.py - line40] - my_log - CRITICAL: 這個是logging模塊的critical信息
五计技、封裝自己的日志輸出類
import logging
class logger(object):
@classmethod
def creat_logger(cls):
# 設置日志收集器酝碳,設置日志收集器等級
my_log = logging.getLogger("my_log")
my_log.setLevel("DEBUG")
# 設置日志輸出格式
str_form = "%(asctime)s - [%(filename)s - line%(lineno)d] - %(name)s - %(levelname)s: %(message)s"
formater = logging.Formatter(str_form)
# 設置日志輸出渠道虎锚,設置日志輸出渠道等級
sh = logging.StreamHandler()
sh.setLevel("DEBUG")
sh.setFormatter(formater)
# 將輸出渠道添加到日志收集器中
my_log.addHandler(sh)
# 設置日志輸出到文件的渠道,設置日志輸出渠道等級
fh = logging.FileHandler(filename="test.log", encoding="utf8")
fh.setLevel("DEBUG")
fh.setFormatter(formater)
# 將輸出到文件渠道添加到日志收集器中
my_log.addHandler(fh)
return my_log
if __name__ == '__main__':
log = logger.creat_logger()
log.info("hello")
輸出結果如下:
2019-11-05 15:42:45,070 - [logger.py - line39] - my_log - INFO: hello
六悦即、其他文件調用日志輸出方法
第一種
其他文件導入封裝日志類,在本文件內創(chuàng)建日志收集器印颤。
import unittest
from register import register
from test_case_read_excel import ReadExcel
from test_project_2.ddt import ddt, data
import logging
from logger import Logger
"""
入參(賬號,密碼1寿酌,密碼2) 預期結果
1.正常注冊的用例:數據庫新用戶名python_new,在6-18位之間它抱,兩個密碼一致秕豫,在6-18位之間 {"code": 1, "msg": "注冊成功"}
2.注冊失敗的用例:賬號已存在python23 {"code": 0, "msg": "該賬戶已存在"}
3.注冊失敗的用例:數據庫新用戶名python_python_python_new,在6-18之外 {"code": 0, "msg": "賬號和密碼不在6-18位之間"}
4.注冊失敗的用例:數據庫新用戶名python_new观蓄,在6-18位之間混移,兩個密碼不一致 {"code": 0, "msg": "兩次密碼不一致"}
5.注冊失敗的用例:數據庫新用戶名python_new,在6-18位之間侮穿,兩個密碼一致歌径,在6-18之外 {"code": 0, "msg": "賬號和密碼不在6-18位之間"}
"""
"""
ddt:
定義:能夠實現數據驅動,通過用例數據亲茅,自動生成測試用例回铛,過程是自動遍歷用例數據,生成測試用例
"""
@ddt
class TestRegister(unittest.TestCase):
# 設置日志收集器克锣,在類外面設置茵肃,類的方法里面調用直接調用變量,在類里面設置袭祟,類的方法里面調用格式是self.log/類名.log
log = Logger.creat_logger()
read = ReadExcel("cases.xlsx", "testcase")
cases = read.read_data_obj()
@data(*cases)
def test_register(self, case):
"""你好"""
# # 打印case對象的所有屬性和屬性值
# print(case.__dict__)
# 第一步:準備用例數據(參數和預期結果)
data = eval(case.data)
expected = eval(case.expected)
# 第二步验残;調用功能函數,獲取實際結果
res = register(*data)
# 第三步:比對實際結果和預期結果
try:
self.assertEqual(res, expected)
except AssertionError as e:
self.read.write_data(case.case_id + 1, 5, "未通過")
# TestRegister.log.info("用例({}):執(zhí)行未通過".format(case.title))
# TestRegister.log.error(e)
self.log.info("用例({}):執(zhí)行未通過".format(case.title))
self.log.error(e)
raise e
else:
self.read.write_data(case.case_id + 1, 5, "通過")
# TestRegister.log.info("用例({}):執(zhí)行通過".format(case.title))
self.log.info("用例({}):執(zhí)行通過".format(case.title))
注意:
- 設置日志收集器榕酒,在類外面設置胚膊,類的方法里面調用直接調用變量,在類里面設置想鹰,類的方法里面調用格式是self.變量名/類名.變量名
- 如果多個文件都創(chuàng)建了日志收集器紊婉,日志輸出就會執(zhí)行多次
第二種
在封裝日志的文件中直接創(chuàng)建日志收集器,在其他文件調用時辑舷,直接導入日志收集器的變量即可喻犁。
import logging
class Logger(object):
@classmethod
def creat_logger(cls):
# 設置日志收集器,設置日志收集器等級
my_log = logging.getLogger("my_log")
my_log.setLevel("DEBUG")
# 設置日志輸出格式
str_form = "%(asctime)s - [%(filename)s - line%(lineno)d] - %(name)s - %(levelname)s: %(message)s"
formater = logging.Formatter(str_form)
# 設置日志輸出渠道何缓,設置日志輸出渠道等級
sh = logging.StreamHandler()
sh.setLevel("DEBUG")
sh.setFormatter(formater)
# 將輸出渠道添加到日志收集器中
my_log.addHandler(sh)
# 設置日志輸出到文件的渠道,設置日志輸出渠道等級
fh = logging.FileHandler(filename="test.log", encoding="utf8")
fh.setLevel("DEBUG")
fh.setFormatter(formater)
# 將輸出到文件渠道添加到日志收集器中
my_log.addHandler(fh)
return my_log
log = Logger.creat_logger()
if __name__ == '__main__':
log = Logger.creat_logger()
log.info("hello")
import unittest
from register import register
from test_case_read_excel import ReadExcel
from test_project_2.ddt import ddt, data
import logging
from logger import log
"""
入參(賬號肢础,密碼1,密碼2) 預期結果
1.正常注冊的用例:數據庫新用戶名python_new碌廓,在6-18位之間传轰,兩個密碼一致,在6-18位之間 {"code": 1, "msg": "注冊成功"}
2.注冊失敗的用例:賬號已存在python23 {"code": 0, "msg": "該賬戶已存在"}
3.注冊失敗的用例:數據庫新用戶名python_python_python_new谷婆,在6-18之外 {"code": 0, "msg": "賬號和密碼不在6-18位之間"}
4.注冊失敗的用例:數據庫新用戶名python_new慨蛙,在6-18位之間辽聊,兩個密碼不一致 {"code": 0, "msg": "兩次密碼不一致"}
5.注冊失敗的用例:數據庫新用戶名python_new,在6-18位之間期贫,兩個密碼一致跟匆,在6-18之外 {"code": 0, "msg": "賬號和密碼不在6-18位之間"}
"""
"""
ddt:
定義:能夠實現數據驅動,通過用例數據通砍,自動生成測試用例玛臂,過程是自動遍歷用例數據,生成測試用例
"""
@ddt
class TestRegister(unittest.TestCase):
read = ReadExcel("cases.xlsx", "testcase")
cases = read.read_data_obj()
@data(*cases)
def test_register(self, case):
"""你好"""
# # 打印case對象的所有屬性和屬性值
# print(case.__dict__)
# 第一步:準備用例數據(參數和預期結果)
data = eval(case.data)
expected = eval(case.expected)
# 第二步封孙;調用功能函數迹冤,獲取實際結果
res = register(*data)
# 第三步:比對實際結果和預期結果
try:
self.assertEqual(res, expected)
except AssertionError as e:
self.read.write_data(case.case_id + 1, 5, "未通過")
log.info("用例({}):執(zhí)行未通過".format(case.title))
log.error(e)
raise e
else:
self.read.write_data(case.case_id + 1, 5, "通過")
log.info("用例({}):執(zhí)行通過".format(case.title))