📜  Python|测试输出到标准输出

📅  最后修改于: 2022-05-13 01:55:01.138000             🧑  作者: Mango

Python|测试输出到标准输出

测试是开发的关键部分,因为在Python执行代码之前没有编译器来分析代码。
给定一个程序,该程序具有一个输出到标准输出 (sys.stdout)的方法。这几乎总是意味着它将文本发送到屏幕。人们喜欢为代码编写一个测试,以证明在给定正确输入的情况下,会显示正确的输出。

使用unittest.mock 模块的patch()函数,可以很简单地模拟出sys.stdout以进行单个测试,然后再将其放回去,而不会出现混乱的临时变量或在测试用例之间泄漏模拟状态。

代码 #1:示例
def urlprint(protocol, host, domain):
    url = '{}://{}.{}'.format(protocol, host, domain)
    print(url)

默认情况下,内置print函数将输出发送到sys.stdout 。为了测试输出是否真正到达那里,将使用替代对象对其进行模拟,然后对发生的情况进行断言。

使用unittest.mock模块的patch()方法可以方便地仅在运行测试的上下文中替换对象,在测试完成后立即将对象恢复到原始状态。


代码#2:上述代码的测试代码

from io import StringIO
from unittest import TestCase
from unittest.mock import patch
import mymodule
  
class TestURLPrint(TestCase):
      
    def test_url_gets_to_stdout(self):
        protocol = 'http'
        host = 'www'
        domain = 'example.com'
        expected_url = '{}://{}.{}\n'.format(protocol, host, domain)
          
        with patch('sys.stdout', new = StringIO()) as fake_out:
            mymodule.urlprint(protocol, host, domain)
            self.assertEqual(fake_out.getvalue(), expected_url)

  • urlprint()函数接受三个参数,测试从为每个参数设置虚拟参数开始。 expected_url 变量设置为包含预期输出的字符串。
  • 为了运行测试, unittest.mock.patch()函数被用作上下文管理器,将sys.stdout的值替换为 StringIO 对象作为替代。
  • fake_out变量是在这个过程中创建的模拟对象。这可以在 with 语句的主体内使用来执行各种检查。当 with 语句完成时,patch 可以方便地将所有内容恢复到测试运行之前的状态。
  • 值得注意的是, Python的某些 C 扩展可能会绕过 sys.stdout 的设置直接写入标准输出。