Книга «Изучаем Python»



Pdf көрінісі
бет113/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   109   110   111   112   113   114   115   116   ...   238
Байланысты:
2 5343781172763690906

name_function.py

def get_formatted_name(first, middle, last):

"""Строит отформатированное полное имя."""

    full_name = first + ' ' + middle + ' ' + last

return full_name.title()

Эта версия должна работать для полных имен из трех компонентов, но тестирова-

ние показывает, что она перестала работать для полных имен из двух компонентов. 

На этот раз файл 

test_name_function .py

 выдает следующий результат:



====================================================================== 



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


.



Достарыңызбен бөлісу:
1   ...   109   110   111   112   113   114   115   116   ...   238




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет