Добрый день. С этого поста начинается серия переводов достаточно объемного туториала по тестированию в Python. Поскольку материал достаточно объемный, переводить и выкладывать буду по частям.
_____________________________________________________________________________________
Начало работы с тестированием в Python.
Этот обучающий материал для всех кто пишет шикарнейшие приложения с помощью Python, но еще не писал к ним тестов.
Тестирование в Python это достаточно большая и комплексная тема, но вы вполне можете начать проверять свои приложения с небольших тестов, которые можно создать в несколько простых действий.
Из этой статьи вы узнаете, как создавать базовые тесты, выполнять их и находить баги до того, как их найдут ваши пользователи! Вы узнаете о доступных инструментах для написания и выполнения тестов, проверите корректность работы своих приложений и наличие уязвимостей в коде с точки зрения информационной безопасности.
Тестируй свой код.
Есть много способов тестировать код. В этой статье мы пройдем от самых простых методов к продвинутым.
Ручное и автоматизированное тестирование
Хорошие новости в том, что вы уже скорее всего создавали тесты, сами того не подозревая. Вспомните первый раз, когда вы запустили свое приложение? Вы экспериментировали с его функциями? Это называется тестирование разведкой и является одной из форм ручного тестирования.
Тестирование разведкой выполняется без первоначального плана. При таком тестировании вы просто прощупываете приложение.
Чтобы получить завершенный набор ручных тестов, вам нужно составить список всех функций в приложении, типы аргументов, которые эти функции могут получить и все ожидаемые результаты. В случае изменения кода, вы должны пройти через весь ваш только что составленный список и проверить каждый пункт.
Звучит не очень весело, не так ли?
В этот момент в игру вступает автоматическое тестирование. Автоматическое тестирование выполняет ваш тестовый план (те части приложения которые вы хотите проверить, в заданном вами порядке, сверяясь с ожидаемыми результатами) с помощью скрипта. Python изначально обладает набором инструментов и библиотек, призванных помочь создать автоматические тесты для вашего приложения. Их мы будем рассматривать дальше.
Интеграционные и юнит тесты.
Мир тестирования никогда не страдал от нехватки терминологии. После того как вы познакомились с ручным и автоматическим, настало время перейти на следующий уровень терминов.
Можно сравнить тестирование с включением фар у автомобиля. Вы включаете фары (шаг тестирования), выходите из машины проверить или просите друга сделать это за вас (подтверждение теста). Тестирование сразу множества компонентов известно как интеграционное тестирование.
Часто, чтобы получить даже простой результат, должно отработать множество компонентов. Это и есть все написанные вами ваши классы, функции и модули.
Одна из главных сложностей при интеграционном тестировании — понять что именно пошло не так. Достаточно сложно диагностировать проблему без определения неработающей части. Если фары не включаются, возможно перегорели лампочки. А может села батарейка? Что насчет генератора? У вас работает машинный компьютер?
Если у вас модная современная машина, она скажет вам когда перегорели лампочки. Это юнит тест.
Юнит тест — это маленькие тесты, проверяющие работу одного компонента. Юнит тесты помогают понять где именно неправильно функционирует ваша программа и быстрее это поправить.
Только что мы разобрали 2 типа тестов:
- Интеграционные тесты проверяют как взаимодействуют компоненты вашей системы
- Юнит тесты проверяют маленькие части вашей системы.
Python позволяет писать как интеграционные так и юнит тесты. Чтобы написать юнит тест к встроенной функции sum() мы сравним выходные данные, предоставляемые функцией с тем, что мы думаем она должна предоставлять.
Например мы знаем, что результат sum() чисел (1,2,3) должен быть 6:
Мы ничего не увидим в REPL, потому что значения корректны.
Если результат отличался бы от нашего, была вызвана ошибка AssertError и сообщение «Should be 6». Попробуйте вызвать эту команду еще раз, но с неправильными значениями, чтобы посмотреть, что произойдет.
Мы видим ошибку AssertError, потому что сумма не равна 6.
Вместо тестирования в REPL, вы можете создать отдельный файл с Python скриптом и назвать его test_sum.py, а затем выполнить его снова. Код файла:
Вы только что написали тестовый кейс и можете вызвать его через командную линию.
Вот наш успешный результат, Everything passed.
В Python, sum() принимает любой итерируемый объект, как первый аргумент. Вы уже использовали список, теперь попробуем кортеж. Создаем новый файл с названием test_sum_2.py и пишем в нем:
Когда мы запустим test_sum_2.py, скрипт выдаст нам ошибку, потому что sum() чисел (1,2,2) равна 5 а не 6. В результате мы получим ошибку, линию кода, на которой она случилась и описание ошибки:
Итак, мы видим как ошибка в коде показывает ошибку в консоли и дополнительную информацию: где эта ошибка произошла и какой результат ожидался.
Написание тестов подобным образом хорошо себя показывает для простых проверок, но что если у нас провалено более одной проверки? Настало время рассмотреть специальные приложения, разработанные для запуска тестов, проверки выходных данных. Эти приложения предоставляют набор инструментов для дебаггинга, диагностических тестов и приложений.
__________________________________________________________________________________________
На этом первая часть закончена. В следующих рассмотрим, какую библиотеку можно взять для тестирования (unittest, nose, pytest), напишем и реализуем первые тесты, а так же познакомимся с несколькими более сложными техниками тестирования.