*«Извините. Произошла ошибка приложения. До свидания.»*
Гнев кипит внутри вас, знакомый с импульсом, когда слышите смех собаки над вами в Duck Hunt. Вы открываете монитор приложения Twilio и находите виновника – опечатку в вашем Dial-вербе.
Звучит печальный тромбон.
Это происходит со всеми нами. И когда вы работаете над своим кодом Twilio, цикл изменения кода, развертывания на веб-сервер и ручного тестирования на вашем телефоне может быстро стать утомительным.
Одна из техник, которую я использую для снижения этой фрустрации, — это написание модульных тестов для своих конечных точек webhook Twilio, пока я работаю над своим приложением. Использование тестового клиента веб-фреймворка для написания этих тестов быстро помогает сохранить мой фокус на приложении, которое я пытаюсь написать, и минимизировать ошибки, которые производят опыт Duck Hunt.
В этом посте мы покажем эту технику в действии с Flask, моим любимым фреймворком для написания приложений Twilio на Python.
— Как написать простую конечную точку конференции Twilio с помощью Flask
— Написать модульный тест с помощью Nose для этой конечной точки
— Расширить этот модульный тест в тестовый случай, который мы можем повторно использовать для всех наших приложений Twilio
— Затем показать, как этот повторно используемый тестовый случай может быть применен к более сложным потокам.
— Зарегистрируйтесь для получения бесплатной учетной записи Twilio
— Установите модуль Python Twilio
— Установите веб-микрофреймворк Flask
— Установите фреймворк тестирования Nose
Для начала мы откроем текстовый редактор в нашей среде Python с установленными модулями Twilio и Flask и создадим простое приложение, которое будет создавать комнату конференции Twilio, используя верб и существительное.
Вот быстрый пример в файле, который мы назовем app.py:
Я думаю, что этот код может быть правильным, но давайте убедимся, написав быстрый модульный тест. Для этого мы откроем другой файл под названием test_app.py. В этом файле мы импортируем наше приложение и определяем модульный тест, используя unittest в стандартной библиотеке Python. Затем мы используем тестовый клиент Flask, чтобы сделать тестовый запрос к приложению и увидеть, бросает ли приложение ошибку.
Затем мы запускаем модульный тест, используя Nose, выдавая следующую команду, Nose пройдет через наш файл модульного теста, найдет все объекты TestCase и выполнит каждый метод, начинающийся с test_:
nosetests -v test_app.py
О, печенье – кажется, у нас есть ошибка.
Д’ох. Имя существительного TwiML для конференции не «Conf», а «Conference». Давайте вернемся к нашему файлу app.py и исправим ошибку.
Теперь, когда строка Conference исправлена, мы можем повторно запустить наши тесты с той же командой, что и выше:
Отлично. И нам не пришлось брать наш телефон, чтобы выяснить ошибку.
Убедиться, что код не бросает ошибку, — это хороший первый шаг, но мы также хотим убедиться, что наше приложение Twilio работает так, как мы намерены. Сначала нам нужно проверить, что приложение возвращает ответ, который Twilio может интерпретировать, убедиться, что оно создает действительный Dial-верб и, наконец, что Dial указывает на правильную комнату конференции.
Для этого мы будем использовать ElementTree, парсер XML из стандартной библиотеки Python. Таким образом мы можем интерпретировать ответ TwiML так же, как Twilio. Давайте посмотрим, как мы можем добавить это в test_app.py:
Теперь запустите оба теста, используя Nose:
Круто. Теперь мы уверены, что это приложение работает так, как мы хотим, помимо возвращения подходящего ответа.
Это здорово, что мы знаем, что наше новое приложение Twilio работает без необходимости ручного тестирования, но приложения Twilio редко используют одну конечную точку webhook. По мере роста сложности нашего приложения мы можем увидеть, что эти два теста будут повторять много кода. Давайте посмотрим, сможем ли мы переработать наши тесты в общий тестовый случай, который мы можем использовать для любых конечных точек webhook Twilio, которые мы построим в будущем.
Для этого мы создадим общий класс TwiMLTest и воспользуемся встроенным методом setUp(), чтобы автоматически создать наш тестовый клиент Flask с каждым тестом.
Хорошее начало – теперь давайте создадим вспомогательный метод, который принимает ответ и выполняет базовую проверку, что это рабочий TwiML.
Наконец, вместо создания нового POST-запроса с каждым тестом, давайте создадим два дополнительных вспомогательных метода, которые будут создавать запросы Twilio для звонков и сообщений, которые мы можем легко расширить с помощью пользовательских параметров. Давайте добавим новый класс в test_app.py.
Отлично – теперь мы можем переработать наши оригинальные тесты для конференции, используя новые вспомогательные методы, что делает тесты намного короче:
Идеально – давайте запустим наши тесты, используя Nose, и посмотрим, все ли у нас хорошо.
И все хорошо с миром.
С нашим общим тестовым случаем для приложений Twilio теперь написание тестов становится быстрым и простым. Мы написали быстрое приложение конференции, протестировали его, используя Nose, и затем переработали эти тесты в общий случай, который можно использовать со всеми нашими приложениями. Используя этот тестовый случай, тестирование наших приложений Twilio, построенных на Flask, может быть быстрым и безболезненным, снижая как количество времени, потраченного на ручное тестирование с вашим телефоном, так и количество раз, когда вам приходится слышать страшный «Ошибка приложения» голос.
Потому что никто не любит слышать это на другом конце телефона.