Python 3 - 带有多个输入和使用嘲讽的打印语句的Unittest。

问题描述 投票:1回答:1

我正在学习Python,几周前,我创建了一个游戏,用户需要猜测一个由用户自己定义的间隔之间的数字。现在我正在学习Unittest,我决定为这个游戏写一个测试模块。但是,由于它需要用户输入4个数字(其中两个定义了随机数产生的范围,一个是用户的猜测,最后一个是一个YN问题,让用户决定是否要继续。

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 - guess比high_param高4 - guess比low_param低5 - guess是一个字符串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个回答
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 调用,因为第一个调用是用来发布欢迎信息的。

第二个测试的工作原理是完全一样的(如果用同样的方式写的话),但是有一个问题:在你的代码中,你捕获了一个通用的而不是特定的异常,这样你的 "break "异常也会被捕获。这通常是不好的做法,所以与其绕过这个问题,不如捕捉特定的异常,如果转换为 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 在你的代码中的块。

© www.soinside.com 2019 - 2024. All rights reserved.