Читаем Изучаем Python онлайн бесплатно
Строка unittest.main() приказывает Python выполнить тесты из этого файла. При запуске test_name_function.py будет получен следующий результат:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Точка в первой строке вывода сообщает, что один тест прошел успешно. Следующая строка говорит, что для выполнения одного теста Python потребовалось менее 0,001 секунды. Наконец, завершающее сообщение OK говорит о том, что все модульные тесты в тестовом сценарии прошли.
Этот результат показывает, что функция get_formatted_name() успешно работает для полных имен, состоящих из имени и фамилии, если только функция не была изменена. В случае внесения изменений в get_formatted_name() тест можно запустить снова. И если тестовый сценарий снова пройдет, мы будем знать, что функция продолжает успешно работать с полными именами из двух компонентов.
Как выглядит сбойный тест? Попробуем изменить функцию get_formatted_name(), чтобы она работала со вторыми именами, — но сделаем это так, чтобы она перестала работать с полными именами из двух компонентов.
Новая версия get_formatted_name() с дополнительным аргументом второго имени выглядит так:
name_function.py
def get_formatted_name(first, middle, last):
"""Строит отформатированное полное имя."""
. .full_name = first + ' ' + middle + ' ' + last
return full_name.title()
Эта версия должна работать для полных имен из трех компонентов, но тестирование показывает, что она перестала работать для полных имен из двух компонентов. На этот раз файл test_name_function.py выдает следующий результат:
(1) E
======================================================================
(2)ERROR: test_first_last_name (__main__.NamesTestCase)
----------------------------------------------------------------------
(3)Traceback (most recent call last):
File "test_name_function.py", line 8, in test_first_last_name
. .formatted_name = get_formatted_name('janis', 'joplin')
TypeError: get_formatted_name() missing 1 required positional argument: 'last'
----------------------------------------------------------------------
(4)Ran 1 test in 0.000s
(5)FAILED (errors=1)
На этот раз информации гораздо больше, потому что при сбое теста разработчик должен знать, почему это произошло. Вывод начинается с одной буквы E (1) , которая сообщает, что один модульный тест в тестовом сценарии привел к ошибке. Затем мы видим, что ошибка произошла в тесте test_first_last_name() в NamesTestCase (2). Конкретная информация о сбойном тесте особенно важна в том случае, если тестовый сценарий состоит из нескольких модульных тестов. В точке (3) мы видим стандартную трассировку, из которой понятно, что вызов функции get_formatted_name('janis', 'joplin') перестал работать из-за необходимого позиционного аргумента.
Также из вывода следует, что был выполнен один модульный тест (4). Наконец, дополнительное сообщение информирует, что тестовый сценарий в целом не прошел и произошла одна ошибка при выполнении тестового сценария (5). Эта информация размещается в конце вывода, чтобы она была видна сразу; разработчику не придется прокручивать длинный протокол, чтобы узнать количество сбойных тестов.
Что делать, если тест не проходит? Если предположить, что проверяются правильные условия, прохождение теста означает, что функция работает правильно, а сбой — что в новом коде добавилась ошибка. Итак, если тест не прошел, изменять нужно не тест, а код, который привел к сбою теста. Проанализируйте изменения, внесенные в функцию, и разберитесь, как они привели к нарушению ожидаемого поведения.
В данном случае у функции get_formatted_name() было всего два обязательных параметра: имя и фамилия. Теперь она требует три обязательных параметра: имя, второе имя и фамилию. Добавление обязательного параметра для второго имени нарушило ожидаемое поведение get_formatted_name(). В таком случае лучше всего сделать параметр второго имени необязательным. После этого тесты для имен с двумя компонентами снова будут проходить, и программа сможет получать также вторые имена. Изменим функцию get_formatted_name(), чтобы параметр второго имени перестал быть обязательным, и снова выполним тестовый сценарий. Если он пройдет, можно переходить к проверке правильности обработки вторых имен.
Чтобы сделать второе имя необязательным, нужно переместить параметр middle в конец списка параметров в определении функции и задать ему пустое значение по умолчанию. Также будет добавлена проверка if, которая правильно строит полное имя в зависимости от того, передается второе имя или нет:
name_function.py
def get_formatted_name(first, last, middle=''):
"""Строит отформатированное полное имя."""
. .if middle:
. . . .full_name = first + ' ' + middle + ' ' + last
. .else:
. . . .full_name = first + ' ' + last
return full_name.title()




