Python. Unit test (Юнит-тесты)
Всем известно, что тестирование программ важно и актуально. Но, зачастую процесс прохождения кейс-тестов довольно трудоёмкий и утомительный. Именно поэтому во многих средах и языках программирования существуют различные средства автоматизации тестов. Одно из таких средств — так называемые «Unit — test». Что это такое? Понятие юнит-теста приходит из объектно-ориентированного программирования. Мы объявляем класс, который должен обладать заданным поведением. Причём, если мы вдруг решили взять и изменить этот класс, то его поведение не должно сломаться. Для того, чтобы проверить, что поведение класса не изменилось, при помощи специальных средств создаться программы, называемые юнит тестами. Они в нужной последовательности вызывают методы класса, выдавая им определённые данные и смотрят, чтобы на выходе было то, что нужно. Если это не так, то выдается сообщения об ошибке.
Нечто подобное есть и в Python-е. Давайте сделаем это на примере одной функции, которая в качестве параметра получает имя и фамилию, а возвращает строку, содержащее имя и фамилию, разделённую пробелом:
def get_formatted_name(first, last):
"""Строит отформатированное полное имя."""
full_name = first + ' ' + last
return full_name.title()
Испытаем ее:
print("Введите 'q' в любое время, чтобы выйти.")
while True:
first = input("\nВведите ваше имя: ")
if first == 'q':
break
last = input("Введите вашу фамилию: ")
if last == 'q':
break
formatted_name = get_formatted_name(first, last)
print("\tВаши отформатированные имя и фамилия: " + formatted_name + '.')
Работая с программой, вы увидите примерно такой диалог:

Допустим, вы решили изменить функцию get_formatted_name(), чтобы она также работала отчествами. При этом необходимо проследить за тем, чтобы функция не перестала правильно работать для имен, состоящих только из имени и фамилии.
Пишем юнит тест
import unittest #Библиотека инстурментария юнит-тестов
from name_function import get_formatted_name #Наша функция
#Тестировочный класс
class NamesTestCase(unittest.TestCase):
"""Тесты для 'name_function.py'."""
def test_first_last_name(self):
"""Имена вида 'Иванов Иван' работают правильно?"""
formatted_name = get_formatted_name('иванов', 'иван')
self.assertEqual(formatted_name, 'Иванов Иван')
unittest.main()
Запускам тест и видим, что все ОК:

Наиболее важным методом является метод assertEqual — он как раз проверяет соответствие выходного значения тому, что должно быть согласно нашему тест-кейсу.
А теперь доработаем нашу функцию, чтобы она выводила еще и отчество:
def get_formatted_name(first, last, middle=''):
"""Строит отформатированное полное имя."""
full_name = first + ' ' + middle+' '+last
return full_name.title()
И дорабатываем наш тест. Помним о том, что функция должна корректно выводить и когда указаны только Фамилия и Имя, и когда указаны Фамилия, Имя и Отчество:
import unittest #Библиотека инстурментария юнит-тестов
from name_function import get_formatted_name #Наша функция
#Тестировочный класс
class NamesTestCase(unittest.TestCase):
"""Тесты для 'name_function.py'."""
def test_first_last_name(self):
"""Имена вида 'Иванов Иванович Иван' работают правильно?"""
formatted_name = get_formatted_name('иванов','иван','иванович')
self.assertEqual(formatted_name, 'Иванов Иванович Иван')
"""Имена вида 'Иванов Иван' работают правильно?"""
formatted_name = get_formatted_name('иванов', 'иван')
self.assertEqual(formatted_name, 'Иванов Иван')
unittest.main()
И опаньки, а функцию то мы сломали:

Что делаем? Исправляем:
def get_formatted_name(first, last, middle=''):
"""Строит отформатированное полное имя."""
if middle:
full_name = first + ' ' + middle+' '+last
else:
full_name = first + ' ' + last
return full_name.title()
Теперь все работает правильно:


Comments
So empty here ... leave a comment!