Python unittest:如何将标准输出消息临时重定向到缓冲区并测试其内容?

Python unittest: How to temporarily redirect stdout messages to a buffer and to test its content?(Python unittest:如何将标准输出消息临时重定向到缓冲区并测试其内容?)
本文介绍了Python unittest:如何将标准输出消息临时重定向到缓冲区并测试其内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在测试期间临时捕获发送给stdout(我们的stderr)的消息,并断言这些消息中是否出现某些字符串模式:

import unittest
class SomeTest(unittest.TestCase):
    def test_stdout(self):
        output = ""
        function_that_writes_to_stdout()
        # How to capture stdout in output temporarily?
        self.assertIn("some message", output)

我找到了similar question,但公认的答案是为所有测试用例捕获发送到stdout的消息。 是的,我知道对发送到stdout的消息进行单元测试并不是很明智。是的,我也知道loggingassertLogs结合使用会更好。我们假设这两个选项在此阶段都不可用。

推荐答案

解决方案1。以下内容适用于我:

import io
import unittest
from contextlib import redirect_stdout

class Test(unittest.TestCase):
    def test_stdout(self):
        buf = io.StringIO()
        with redirect_stdout(buf):
            print("foo!")
        self.assertIn("foo", buf.getvalue())

buf.getvalue()将包含整个输出,包括 个字符。

解决方案2.要模仿assertLogs的行为,可以通过以下方法扩展unittest.TestCase

class StdoutRedirectionContext():
    class ListIO():
        def __init__(self):
            # Container for messages sent to stdout.
            self.output = []
        def write(self, s):
            # Filter empty strings or naked newline characters.
            if s in ("
", ""): return
            self.output.append(s)

    def __enter__(self):
        self._buf = self.ListIO()
        self._ctx = redirect_stdout(self._buf)
        self._ctx.__enter__()
        return self._buf

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self._ctx.__exit__(exc_type, exc_value, exc_traceback)

class TestCase(unittest.TestCase):
    def assertStdout(self):
        return StdoutRedirectionContext()
这里,StdoutRedirectionContext充当上下文管理器,单个消息将被收集在output列表中。扩展的TestCase可用于在标准输出上断言消息:

class AnotherTest(TestCase):
    def test_stdout(self):
        with self.assertStdout() as cm:
            print("foo!")
            print("bar!")
        self.assertIn("foo!", cm.output)
        self.assertIn("baz!", cm.output)

以上将产生以下输出:

======================================================================
FAIL: test_stdout (__main__.AnotherTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "executor_test.py", line 440, in test_stdout
    self.assertIn("baz!", cm.output)
AssertionError: 'baz!' not found in ['foo!', 'bar!']

这篇关于Python unittest:如何将标准输出消息临时重定向到缓冲区并测试其内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)