简单的但功能强大的日志行断言和验证。
项目描述
日志断言
什么?
Python unittests的简单日志断言机制。
为什么?
正如民意所诉,您还必须测试您程序中的日志调用。
使用logassert
现在非常简单。
太棒了!我该如何使用它?
以两种非常不同的方式暴露了相同的功能,一种更适合pytest语义,另一种更适合经典单元测试。
对于pytest
您只需在测试参数中声明logs
,它就像任何其他固定装置一样工作。
然后您只需检查(使用assert
,如通常与pytest一样)是否特定行出现在特定级别的日志中。
示例
def test_bleh(logs)
(...)
assert "The meaning of life is 42" in logs.debug
实际上,您所写的行是一个正则表达式,所以您可以完全做到(如果您不确定生命的意义是什么)
assert "The meaning of life is \d+" in logs.debug
指示的字符串将在日志行中进行搜索,不需要与整行完全匹配。如果您需要这样,只需像使用任何正则表达式一样指示即可。
assert "^The meaning of life is \d+$" in logs.debug
以类似的方式,您还可以表达希望检查它是否位于日志行的开头或结尾。
注意:检查的消息是最终的,在日志系统将所有指示的参数替换到指示的字符串之后。
如果您想验证某个文本已记录,无论级别如何,只需这样做
assert "The meaning of life is 42" in logs.any_level
要验证某些文本未被记录,只需使用Python的语法!例如
assert "A problem happened" not in logs.error
但是我不喜欢正则表达式,我想要确切的字符串
那么您只需从logassert
导入Exact
,并用它来包装字符串。
例如,在这种情况下,..
意味着正好两个点,完全没有正则表达式的语义。
assert Exact("The meaning of life is ..") in logs.any_level
无论如何,我喜欢旧的搜索多个字符串的行为
那么您可能想从logassert
导入Multiple
,并在每个调用中包装不同的字符串以获得经典行为。
例如
assert Multiple("life", "meaning", "42") in logs.any_level
如果我想要检查没有任何内容被记录呢?
最简单的方法是使用可以从logassert
导入的NOTHING
验证器。
assert NOTHING in logs.debug
注意,使用否定(...NOTHING not in logs...
)没有意义:在测试级别知道“已记录某些内容”并没有真正的作用,您应该改进测试以具体验证什么被记录。
打破“每行障碍”
有时验证多个连续记录的行并确保它们按顺序记录,构建一个“复合消息”是有用的。
为了控制记录的行,您可以使用接收所有要验证的行的Sequence
辅助工具(默认情况下为正则表达式,但您也可以使用其他辅助工具)。
assert Sequence(
"Got 2 errors and \d+ warnings:",
Exact(" error 1: foo"),
Exact(" error 2: bar"),
) in logs.debug
示例
记录之后...
person = "madam"
item = "wallet"
logger.debug("Excuse me %s, you dropped your %s", person, item)
...以下测试将仅通过
assert "Excuse me .*?, you dropped your wallet" in logs.debug
然而,以下将失败(不同的文本)...
assert "Excuse me .*?, you lost your wallet" in logs.debug
...在您的测试中产生此消息
assert for regex 'Excuse me .*?, you lost your wallet' check in DEBUG, failed; logged lines:
DEBUG 'Excuse me madam, you dropped your wallet'
这个也会失败(不同的级别)...
assert "Excuse me .*?, you dropped your wallet" in logs.info
...在您的测试中产生此消息
assert for regex 'Excuse me .*?, you dropped your wallet' check in INFO, failed; logged lines:
DEBUG 'Excuse me madam, you dropped your wallet'
一个更复杂的示例,有多个日志行,并且有特定的断言
logger.info("Starting system")
places = ['/tmp/', '~/temp']
logger.debug("Checking for config XYZ in all these places %s", places)
logger.warning("bad config XYZ")
assert "bad config XYZ" in logs.debug
看看测试失败消息是如何非常有帮助的
assert for regex 'bad config XYZ' check in DEBUG, failed; logged lines:
INFO 'Starting system'
DEBUG "Checking for config XYZ in all these places ['/tmp/', '~/temp']"
WARNING 'bad config XYZ'
关于重复验证呢?
有时需要验证某物仅记录一次(例如欢迎消息)。在这种情况下,使用reset
方法非常有用。
参见以下测试序列
def test_welcoming message(logs):
logger.info("foo") # first log! it should trigger the welcoming message
assert "Welcome" in logs.info
logs.reset()
logger.info("foo") # second log! it should NOT trigger the welcoming message
assert "Welcome" not in logs.info
对于经典测试用例
您只需要调用此模块的setup()
,传入测试用例实例和您想要监督的记录器。
例如
class MyTestCase(unittest.TestCase):
"""Example."""
def setUp(self):
logassert.setup(self, 'mylogger')
在示例中,mylogger
是您要监督的记录器的名称。如果您的代码的不同子系统使用不同的记录器记录,则该测试器不会注意到。
然后,为了使用它,只需调用assertLogged
方法及其家族,传入您想要找到的所有字符串。这是向后兼容的默认行为。
示例
def test_blah(self):
(...)
self.assertLoggedDebug('secret', 'life', '42')
该行将检查“secret”、“life”和“42”在同一个记录调用中都被记录,在DEBUG级别。
因此,如果您记录了这些,则测试将通过
logger.debug("The secret of life, the universe and everything is %d", 42)
注意,检查的消息是带有所有参数替换的消息。
但是,如果您记录了以下任何内容,则测试将失败(第一个因为它缺少一个字符串,第二个因为它有错误的日志级别):
logger.debug("The secret of life, the universe and everything is lost")
logger.info("The secret of life, the universe and everything is 42")
我可以测试什么?
您将可以使用多个断言方法
-
self.assertLogged
:将检查字符串是否被记录,无论级别如何 -
self.assertLoggedLEVEL
(其中LEVEL
是错误、警告、信息或调试之一):将检查字符串是否在特定级别被记录。 -
self.assertNotLogged
:将检查字符串没有被记录,无论级别如何。 -
self.assertNotLoggedLEVEL
(其中LEVEL可以是Error、Warning、Info或Debug之一):将检查字符串是否未在该特定级别上记录。
不错!但是...
如果您需要帮助,或有任何问题,或者发现了任何问题,请在此处打开工单。
感谢您抽出宝贵时间。
项目详情
下载文件
下载适用于您平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
logassert-7.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bf7598c00c4c17569dded3bcc753a2719f17a426b09622290f2ee3286e2e2060 |
|
MD5 | 817e20d266ff5094111fc37706cd113d |
|
BLAKE2b-256 | 88dbc9cf2a615b720a6caf55c60611a72ae8cc9ab907e2c24bfeaffd07c0677a |
logassert-7-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 200d25f2e984a2099a07d6c37fde46b96fb8c215375f705914741e4a09ee335c |
|
MD5 | f2e1d00c386e7b14cb349654a1cbb0b6 |
|
BLAKE2b-256 | 7f88eb9200795d281bb9e6bd7aa660c4f3f470023b5fc758f251c115965b95d5 |