Python 3 - Unittest с несколькими входами и оператором печати с использованием насмешек - PullRequest
1 голос
/ 22 апреля 2020

Я изучаю Python и несколько недель go Я создал игру, в которой пользователь должен угадать число между интервалами, определенными самим пользователем. Теперь, когда я изучаю 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

Мне удалось смоделировать один вход в первом методе, однако я не знаю как утверждать с оператором печати в качестве вывода ситуации. Для других ситуаций мне нужно смоделировать более одного ввода, и там я застрял.

Как я могу решить эти две проблемы?

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

1 Ответ

0 голосов
/ 22 апреля 2020

Ваша первая проблема - выбраться из l oop. Вы можете сделать это, добавив побочный эффект к фиктивной функции 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!')

Обратите внимание, что необходимо добавить побочный эффект к вызову second print, так как первый используется для выдачи приветственного сообщения.

Второй тест будет работать точно так же (если он будет написан одинаково), но для одной проблемы: в вашем коде вы поймете шаблон c вместо укажите исключение c, так что ваше исключение "перерыв" также будет перехвачено. Как правило, это плохая практика, поэтому вместо обхода этого лучше поймать указанное c исключение, которое возникает, если преобразование в 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 блок в вашем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...