如何在pytest测试类的方法中引入caplog fixture?
在pytest的AsyncTestCase测试类中使用caplog fixture
因为你的测试类继承自AsyncTestCase(属于unittest风格的测试类),这类测试方法不能像普通pytest函数那样直接接收fixture参数,不过pytest提供了专门的方式来给这类测试注入fixture,具体有两种常用方法:
方法一:用@pytest.mark.usefixtures注入caplog
你可以给整个测试类或者单个测试方法添加这个装饰器,把caplog fixture注入到测试实例中,之后就能通过self.caplog来访问它。
修改后的代码示例
import pytest from tornado.testing import AsyncTestCase, gen_test # 导入你需要的其他模块:bind_unused_port, NullContext, EchoServer, IOStream, app_log等 @pytest.mark.usefixtures("caplog") class TestConnection(AsyncTestCase): '''Integration test''' @gen_test def test_connecting_to_server(self): '''Connecting to the TCPserver''' client = server = None try: sock, port = bind_unused_port() with NullContext(): server = EchoServer() server.add_socket(sock) client = IOStream(socket.socket()) # 获取注入的caplog实例 caplog = self.caplog # 可选:设置要捕获的日志级别,比如只捕获INFO及以上 caplog.set_level("INFO") # 可选:指定只捕获app_log这个logger的日志 caplog.set_level("INFO", logger=app_log.name) # 执行你的测试操作 yield client.connect(('localhost', port)) yield client.write(b'hello\n') yield gen.moment # 检查日志是否符合预期 # 方式1:检查日志文本中是否包含目标字符串 assert 'decode' in caplog.text # 方式2:更精确地遍历日志记录,匹配logger和内容 assert any( record.name == app_log.name and 'decode' in record.message for record in caplog.records ) # 替换原来的assert False为实际的断言逻辑 # assert False finally: if server is not None: server.stop() if client is not None: client.close()
如果不想给整个类注入,也可以只给单个测试方法加装饰器:
class TestConnection(AsyncTestCase): '''Integration test''' @pytest.mark.usefixtures("caplog") @gen_test def test_connecting_to_server(self): # 方法内同样用self.caplog访问 # ... 剩余代码同上
方法二:使用autouse fixture自动注入
如果你希望所有测试方法都能自动使用caplog,可以定义一个autouse的fixture,把caplog绑定到测试实例上:
import pytest @pytest.fixture(autouse=True) def inject_caplog(self, caplog): self.caplog = caplog class TestConnection(AsyncTestCase): # ... 测试方法中直接用self.caplog即可
为什么原来的ExpectLog可能不工作?
Tornado的ExpectLog是基于自身的日志捕获机制实现的,和pytest的caplog可能存在兼容性问题(比如两者的上下文管理器冲突)。改用caplog可以更好地融入pytest的测试生态,而且功能更灵活,比如可以事后检查所有日志记录、过滤特定logger或级别等。
内容的提问来源于stack exchange,提问作者Liviu
相关产品推荐
相关产品推荐

