【问题标题】:Python 3 - Unittest with multiple inputs and print statement using mockingPython 3 - 具有多个输入的单元测试和使用模拟的打印语句
【发布时间】:2020-04-21 23:25:20
【问题描述】:

我正在学习 Python,几周前我创建了一个游戏,用户需要猜测用户自己定义的间隔之间的数字。现在我正在学习 Unittest,我决定为游戏编写一个测试模块。然而,由于它需要来自用户的 4 个输入(其中两个定义了将生成随机数的范围,一个是用户的猜测,最后一个是一个 Y/N 问题供用户决定他是否想要继续。

import random

def main():

    print('Welcome to the guess game!')

    while True:
        try:

            low_param = int(input('Please enter the lower number: '))
            high_param = int(input('Please enter the higher number: ')) 

            if high_param <= low_param:
                print('No, first the lower number, then the higher number!')

            else:
                break

        except:
            print('You need to enter a number!')


    while True:
        try:
            result = random.randint(low_param, high_param)
            guess = int(input(f'Please enter a number between {low_param} and {high_param}: '))

            if low_param <= guess <= high_param:
                if result == guess:
                    print('Nice, dude!')
                    break

                else:
                    print ('Not yet, chap')

                while True:
                    try_again = input('Would you like to try again? (Y/N) ')

                    if try_again.lower() == 'n':
                        break

                    elif try_again.lower() == 'y':
                        print('If you consider yourself capable...')
                        break

                    else:
                        pass

                if try_again.lower() == 'n':
                    print('Ok, maybe next time, pal :v')
                    break                
            else:
                print(f'Your guess must be between {low_param} and {high_param}')

        except:
            print('Are you sure you entered a number?')


if __name__ == '__main__':
    main()

在测试中,我想创建一些方法来验证以下情况:

1 - low_param 或 high_param 不是数字 2 - low_param 高于 high_param 3 - 猜测高于 high_param 4 - 猜测低于 low_param 5 - 猜测是一个字符串 6 - try_again 既不是 Y 也不是 N

我设法在第一种方法上模拟了一个输入,但是我不知道如何将 print 语句断言为情况输出。 对于其他情况,我需要模拟多个输入,然后我就卡住了。

我该如何解决这两个问题?

import unittest
from unittest.mock import patch
from randomgame import main

class TestRandom(unittest.TestCase):


    @patch('randomgame.input', create = True)
    def test_params_input_1(self, mock_input):

        mock_input.side_effect = ['foo']
        result = main()

        self.assertEqual(result, 'You need to enter a number!')

    @patch('randomgame.input2', create = True)
    def test_params_input_2(self, mock_inputs_2):

        mock_inputs_2.side_effect = [1 , 0]
        result = main()

        self.assertEqual(result, 'No, first the lower number, then the higher number!')



if __name__ == '__main__':
    unittest.main()

【问题讨论】:

    标签: python unit-testing input mocking


    【解决方案1】:

    您的第一个问题是跳出循环。您可以通过向引发异常的模拟 print 函数添加副作用来做到这一点,并在测试中忽略该异常。模拟的print 也可用于检查打印的消息:

    @patch('randomgame.print')
    @patch('randomgame.input', create=True)
    def test_params_input_1(self, mock_input, mock_print):
        mock_input.side_effect = ['foo']
        mock_print.side_effect = [None, Exception("Break the loop")]
        with self.assertRaises(Exception):
            main()
        mock_print.assert_called_with('You need to enter a number!')
    

    请注意,您必须将副作用添加到第二个 print 调用,因为第一个用于发出欢迎消息。

    第二个测试的工作方式完全相同(如果以相同的方式编写),但有一个问题:在您的代码中,您捕获的是通用异常而不是特定异常,因此您的“中断”异常也将被捕获。这通常是不好的做法,因此与其解决此问题,不如捕获在转换为 int 失败时引发的特定异常:

    while True:
        try:
            low_param = int(input('Please enter the lower number: '))
            high_param = int(input('Please enter the higher number: '))
            if high_param <= low_param:
                print('No, first the lower number, then the higher number!')
            else:
                break
        except ValueError:  # catch a specific exception
            print('You need to enter a number!')
    

    代码中的第二个try/catch 块也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2020-10-14
      相关资源
      最近更新 更多