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!