我正在学习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()
你的第一个问题是要脱离循环。你可以通过在被模拟的游戏中添加一个副作用来实现。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
在你的代码中的块。