简体   繁体   English

如何测试 python class 的控制台打印?

[英]How to test the print to console of a python class?

I want to test what the print output of a class I am making is.我想测试我正在制作的 class 的打印 output 是什么。 I have tried several approaches based on answers on stackoverflow, but some of the answers are python 2.7 specific, and I couldn't translate them.我已经根据 stackoverflow 上的答案尝试了几种方法,但其中一些答案是 python 2.7 特定的,我无法翻译它们。 This is my class:这是我的 class:

class trool:

    def __init__(self, num : int):
        """
        Ternary datatype
        """
        if num:
            num = 1
        if num == 0:
            num = -1
        if num is None:
            num = 0
            
        self._num = num

    def __str__(self) -> str:
        if self._num == 1:
            return 'True'
        elif self._num == -1:
            return 'False'
        else: 
            return 'Unknown'

    def __repr__(self):
        return self.__str__()

I have tried some different ways, but they all give me something weird我尝试了一些不同的方法,但它们都给了我一些奇怪的东西

class TestFunctions(unittest.TestCase):

    def setUp(self) -> None:
        self.true       = trool(True)
        self.unknown    = trool(None)
        self.false      = trool(False)

    @patch('builtins.print')
    def test_print1(self, mock_print):
        # The actual test
        print(self.true)
        mock_print.assert_called_with(True)
        print(self.false)
        mock_print.assert_called_with(False)

        # Showing what is in mock
        sys.stdout.write(str( mock_print.call_args ) + '\n')
        sys.stdout.write(str( mock_print.call_args_list ) + '\n')

gives the error给出错误

Expected: print(True) 
Actual: print(True)

which suggests to me that one of the prints prints the boolean and the other prints the string, but I'm not sure.这向我表明其中一张打印的是 boolean 而另一张打印的是字符串,但我不确定。 Another test I tried:我尝试的另一个测试:

    def test_print2(self):
        capturedOutput = StringIO()
        sys.stdout = capturedOutput
        print(trool(True))
        sys.stdout = sys.__stdout__
        print('Captured', capturedOutput.getvalue())
        self.assertEqual('True', capturedOutput.getvalue())

gave me this给了我这个

AssertionError: 'True' != 'True\n'

but I don't know why I get the '\n' in there.但我不知道为什么我在那里得到'\ n'。 Any feedback is welcome.欢迎任何反馈。

In your first test, it's unclear why you would expect it to pass, because you haven't mentioned what your goal for this class is.在您的第一次测试中,不清楚您为什么希望它通过,因为您没有提到您对这个 class 的目标是什么。 You created an object that prints out as 'True' , but is not equal to True .您创建了一个 object 打印为'True' ,但不等于True (In fact, no two trool objects are ever equal to each other, either.) The results of that test line up perfectly with that. (事实上,也没有两个trool对象彼此相等。)该测试的结果与此完全一致。 So either you want a different class, or a different test.因此,您要么想要不同的 class,要么想要不同的测试。 Is there any chance you wanted to test the output of str() instead of the input to print() ?您是否有机会测试str()的 output 而不是print()的输入? That would be a simpler test, and since print() calls str() , it's unclear to me why you would need to test print at all.那将是一个更简单的测试,并且由于print()调用str() ,我不清楚为什么您需要测试print

For your second test, print() adds a newline ( \n ) to the end of its arguments by default.对于您的第二个测试, print()默认情况下会在其 arguments 的末尾添加一个换行符 ( \n )。 You can see this by printing to the console: subsequent text will be printed to the following line, not the same line.您可以通过打印到控制台看到这一点:后续文本将打印到下一行,而不是同一行。

If you don't want to print the newline, you can change the end keyword argument from its default '\n' to '' .如果您不想打印换行符,可以将end关键字参数从默认'\n'更改为'' You might also want to force it to flush, as output is often line-buffered:您可能还想强制它刷新,因为 output 通常是行缓冲的:

print(trool(True), end='', flush=True)

Whenever you change a value, run code that might fail, then change it back, you should use try / finally or a context manager to ensure you really do change it back.每当您更改值,运行可能失败的代码,然后将其改回时,您应该使用try / finally或上下文管理器来确保您确实将其改回。

If you're calling print yourself in your test, there's an easier and safer way to test the output of print than messing around with stdout .如果您在测试中自己调用print ,则有一种更简单、更安全的方法来测试print的 output ,而不是弄乱stdout The file keyword argument lets you send its output straight to your StringIO object. file关键字参数允许您将其 output 直接发送到您的 StringIO object。

Of course, like with your first test, there's no clear need to test print here, when you could be testing str .当然,就像您的第一次测试一样,当您可以测试str时,这里没有明确需要测试print

See also the print() documentation .另请参阅print()文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM