Основы тестирования на Python: unittest |
08.04.2021 00:00 |
Автор: Энди Найт (Andy Knight) Обзор unittest – это стандартный Python-фреймворк для юнит-тестов. Создатели вдохновлялись JUnit, и он включается в стандартный дистрибутив CPython. unittest содержит базовый класс TestCase, дающий методы для утверждений и рутин настройки и очистки. Все классы тест-кейсов должны наследоваться от TestCase. Каждый метод в подклассе TestCase, чье имя начинается с "test", будет прогоняться как тест-кейс. Тесты можно группировать и загружать с использованием класса TestSuite и методов загрузки – используя их совместно, можно создавать свои собственные тест-загрузчики. unittest также может генерировать XML-отчеты (как и JUnit), используя unittest-xml-reporting. unittest поддерживается и в Python 2, и в Python 3. Однако для версий старше Python 2.7 нужно пользоваться портированием unittest2. Установка Базовый unittest не нуждается в отдельной установке, потому что поставляется вместе с Python. Дополнительные модули можно при необходимости установить через pip. > pip install unittest2 Структура проекта Модули кода продукта и тест—код unittest должны находиться в разных пакетах Python внутри одного проекта. Тест-модули должны иметь имена test_*.py, и должны находиться в пакетах, чтобы они были обнаружены при запуске тестов. Помните, что пакет Python – это просто директория с файлом по имени “__init__.py“. Product code modules and unittest test code modules should be placed into separate Python packages within the same project. Test modules must be named “test_*.py” and must be put into packages in order for discovery to work when launching tests. Remember, a Python package is simply a directory with a file named “__init__.py“. [project root directory] Пример кода Демо-проект по имени example-py-unittest находится в моем репозитории GitHub python-testing-101. Структура проекта такова: example-py-unittest Модуль com.automationpanda.example.calc содержит класс Calculator с базовыми математическими методами. class Calculator(object): @property def add(self, a, b): def subtract(self, a, b): self._last_answer = a - b return self.last_answer def multiply(self, a, b): def divide(self, a, b): Модуль com.automationpanda.tests.test_calc содержит подкласс unittest.TestCase, показанный ниже. Тест-класс использует метод setup для создания объекта Calculator, используемого в каждом методе. Методы утверждений – это assertEqual и assertRaises. Свежая копия CalculatorTest создается для запуска каждого тест-метода. from com.automationpanda.example.calc import Calculator def test_add(self): def test_subtract(self): def test_subtract_negative(self): def test_multiply(self): def test_divide(self): def test_divide_by_zero(self): Запуск тестов Для запуска тестов из командной строки измените директорию на корневую директорию проекта и запустите модуль unittest напрямую из команды python: # Найти и прогнать все тесты проекта > python -m unittest discover # Запустить все тесты модуля > python -m unittest com.automationpanda.tests.test_calc # Запустить все тесты для тест-класса > python -m unittest com.automationpanda.tests.test_calc.CalculatorTest # Запустить все тесты в конкретном Python-файле > python -m unittest com/automationpanda/tests/test_calc.py Результат тестов должен выглядеть примерно так: > python -m unittest discover Чтобы создать XML-отчеты, установите unittest-xml-reporting и добавьте следующую "main"-логику в конец модуля тест-кейса. Пример ниже создаст и сохранит XML-отчет в директорию по имени "test reports". if __name__ == '__main__': unittest.main( Давайте запустим тест-модуль напрямую из командной строки. # Запуск тест-модуля напрямую За и против unittest стар и надежен. Он поставляется с Python из коробки и дает базовый, универсальный тест-класс. Множество других тест-фреймворков совместимы с unittest. Однако он немного неповоротлив – он навязывает наследование классов вместо того, чтобы разрешать функции в качестве тест-кейсов. Стиль ООП не очень "пайтоновский", по ощущениям. Тесты также нельзя параметризировать. Я рекомендую использовать unittest, если вам нужен базовый фреймворк для юнит-тестов без дополнительных зависимостей. В прочих случаях есть фреймворки получше – например, pytest. |