python仿写print,Python 3-具有模拟功能的多个输入和打印语句的单元测试

I'm studying Python and a few weeks ago I had created a game which the user needs to guess the number between an interval defined by the user himself. Now that I'm learning about Unittest, I decided to write a test module for the game. However, as it takes 4 inputs from the user (two of them defines the range which the random number will be generated, one is the user's guess and the last is an Y/N question for the user to decide whether or not he wants to continue.

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()

On the tests, I want to create some methods to verify the following situations:

1 - low_param or high_param aren't numbers

2 - low_param is higher than high_param

3 - guess is higher than high_param

4 - guess is lower than low_param

5 - guess is a string

6 - try_again is neither Y nor N

I managed to mock one input on the first method, however I don't know how to assert with a print statement as the situation output.

For the other situations I need to mock more than one input, and there I got stuck.

How can I solve those two problems?

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()

解决方案

Your first problem is to get out of the loop. You can do this by adding a side effect to the mocked print function that raises an exception, and ignore that exception in the test. The mocked print can also be used to check for the printed message:

@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!')

Note that you have to add the side effect to the second print call, as the first one is used for issuing the welcome message.

The second test would work exactly the same (if written the same way), but for one problem: in your code you catch a generic instead of a specific exception, so that your "break" exception will also be caught. This is generally bad practice, so instead of working around this it is better to catch the specific excpetion that is raised if the conversion to int fails:

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!')

The same is true for the second try/catch block in your code.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值