name_function.py
def get_formatted_name(first, middle, last):
"""Строит отформатированное полное имя."""
full_name = first + ' ' + middle + ' ' + last
return full_name.title()
Эта версия должна работать для полных имен из трех компонентов, но тестирова-
ние показывает, что она перестала работать для полных имен из двух компонентов.
На этот раз файл
test_name_function .py
выдает следующий результат:
E
======================================================================
ERROR: test_first_last_name (__main__.NamesTestCase)
----------------------------------------------------------------------
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'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
На этот раз информации гораздо больше, потому что при сбое теста разработчик
должен знать, почему это произошло. Вывод начинается с одной буквы E , которая
сообщает, что один модульный тест в тестовом сценарии привел к ошибке. Затем мы
видим, что ошибка произошла в тесте
test_first_last_name()
в
NamesTestCase
.
Конкретная информация о сбойном тесте особенно важна в том случае, если тестовый
сценарий состоит из нескольких модульных тестов. В точке мы видим стандартную
трассировку, из которой понятно, что вызов функции
get_formatted_name('janis',
'joplin')
перестал работать из-за необходимого позиционного аргумента.
214 Глава 11 • Тестирование
Также из вывода следует, что был выполнен один модульный тест . Наконец, до-
полнительное сообщение информирует, что тестовый сценарий в целом не прошел
и произошла одна ошибка при выполнении тестового сценария . Эта информация
размещается в конце вывода, чтобы она была видна сразу; разработчику не придется
прокручивать длинный протокол, чтобы узнать количество сбойных тестов.
Реакция на сбойный тест
Что делать, если тест не проходит? Если предположить, что проверяются правильные
условия, прохождение теста означает, что функция работает правильно, а сбой — что
в новом коде добавилась ошибка. Итак, если тест не прошел, изменять нужно не тест,
а код, который привел к сбою теста. Проанализируйте изменения, внесенные в функ-
цию, и разберитесь, как они привели к нарушению ожидаемого поведения.
В данном случае у функции
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()
В новой версии
get_formatted_name()
параметр
middle
не обязателен. Если второе
имя передается функции (
if
middle:
), то полное имя будет содержать имя, второе
имя и фамилию. В противном случае полное имя состоит только из имени и фа-
милии. Теперь функция должна работать для обеих разновидностей имен. Чтобы
узнать, работает ли функция для имен из двух компонентов, снова запустите
test_name_function .py
:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Тестирование функции 215
Теперь тестовый сценарий проходит. Такой исход идеален; он означает, что функ-
ция снова работает для имен из двух компонентов и нам не пришлось тестировать
функцию вручную. Исправить ошибку было несложно, потому что сбойный тест
помог выявить новый код, нарушивший существующее поведение.
Добавление новых тестов
Теперь мы знаем, что
get_formatted_name()
работает для простых имен, и мо-
жем написать второй тест для имен из трех компонентов. Для этого в класс
NamesTestCase
добавляется еще один метод:
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""Тесты для 'name_function.py'."""
def test_first_last_name(self):
"""Работают ли такие имена, как 'Janis Joplin'?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
def test_first_last_middle_name(self):
"""Работают ли такие имена, как 'Wolfgang Amadeus Mozart'?"""
formatted_name = get_formatted_name(
'wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
unittest.main()
Новому методу присваивается имя
test_first_last_middle_name()
. Имя метода
должно начинаться с
test_
, чтобы этот метод выполнялся автоматически при запуске
test_name_function .py
. В остальном имя выбирается так, чтобы оно четко показывало,
какое именно поведение
get_formatted_name()
мы тестируем. В результате при сбое
теста вы сразу видите, к каким именам он относится. Не нужно опасаться длинных
имен методов в классах
TestCase
: имена должны быть содержательными, чтобы до-
нести информацию до разработчика в случае сбоя, а поскольку Python вызывает их
автоматически, вам никогда не придется вручную вводить эти имена при вызове.
Чтобы протестировать функцию, мы вызываем
get_formatted_name()
c тремя
компонентами , после чего используем
assertEqual()
для проверки того, что
возвращенное полное имя совпадает с ожидаемым. При повторном запуске
test_
name_function .py
оба теста проходят успешно:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Отлично! Теперь мы знаем, что функция по-прежнему работает с именами
из двух компонентов, как
Janis
Joplin
, но можем быть уверены в том, что она
216 Глава 11 • Тестирование
сработает и для имен с тремя компонентам — такими, как
Wolfgang
Amadeus
Mozart
.
Достарыңызбен бөлісу: |