что такое фикстура pytest

Что такое фикстура pytest

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Что пишут в блогах

Привет! В блоге появляется мало новостей, потому что все переехало в telegram.

Стоимость в цвете — 2500 рублей самовывозом (доставка еще 500-600 рублей, информация по ней будет чуть позже)

Заказать — https://shop.testbase.ru/buy/book. Пока самовывоз (см ниже где и когда!!). С почтой разберемся чуть позже.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Онлайн-тренинги

Что пишут в блогах (EN)

Разделы портала

Про инструменты

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytestАвтор: Джош Грант (Josh Grant)
Оригинал статьи
Перевод: Ольга Алифанова

Продолжая рассказывать о чудесных возможностях Pytest, я хочу немного поговорить о старой, но прекрасной фиче – о фикстурах.

Фикстуры – интересная и часто смущающая новичков тема в Pytest. Вначале они кажутся контринтуитивными и попросту неправильными, но как только вы поймете, как это работает, фикстуры станут неотъемлемой частью хорошего кода Pytest.

Начнем с начала. Что такое фикстура? Это функция, несущая логику, применяемую в определенном контексте. Предположим для примера, что мы хотим протестировать библиотеку генератора случайных чисел по имени Rando. Мы можем использовать фикстуры для тестирования объект-экземпляра:

Эта фикстура возвращает экземпляр Rando по имени rando, который можно передавать в функции. Каждая функция получает свой собственный независимый экземпляр rando, который можно использовать в логическом теле функции. Это кажется довольно простым синтаксически, но тут происходит кое-что интересное.

Во-первых, мы не используем в коде объектно-ориентированное программирование. Две вышеуказанных функции не обязаны быть членами класса. Фикстура может использоваться этими функциями, и не должна сохранять состояние между тестами.

Приведу пример объектно-ориентированного псевдокода:

Это более традиционный подход, который тоже сработает с классами в Python. Удивительный красивый момент тут в том, что ООП не требуется для работы с Pytest. И, как оказывается, для работы с Pytest ООП лучше вовсе не использовать.

Чтобы понять, почему, давайте рассмотрим другой клевый аспект использования фикстур: фикстуры могут пользоваться другими фикстурами.

Предположим, что в вышеприведенном примере генератора случайных чисел можно создать и передать RandoSeed в экземпляр Rando. Если мы хотим одновременно проверить и использовать его, мы создадим такие фикстуры:

(Не волнуйтесь, если вам не знакома генерация случайных чисел. Суть тут в подходе к тесту, а не в конкретных тестируемых свойствах. Генерация случайных чисел – сложная штука).

В коде выше использование фикстуры для RandoSeed полностью отделено от экземпляра генератора случайных чисел. Оба можно использовать в тестах и фикстурах независимо. Нет нужны выделять эти тестовые функции в разные классы или пытаться настраивать или умалять функциональность. Все работает как и должно. Тесты можно добавлять, убирать и изменять индивидуально по необходимости, не жонглируя структурами классов.

Эти примеры – это только начало использования фикстур в Python, но они дают общее представление о том, как работают фикстуры и какие проблемы они решают. Жизнь с фикстурами Pytest хороша!

Источник

Как в Яндексе используют PyTest и другие фреймворки для функционального тестирования

Всем привет! Меня зовут Сергей, и в Яндексе я работаю в команде автоматизации тестирования сервисов монетизации. Перед каждой командой, которая занимается задачами автоматизации тестирования, встает вопрос: «Какой [фреймворк|инструмент] выбрать для написания своих тестов?» В этом посте я хочу помочь вам на него ответить. Если быть конкретнее, речь пойдет об инструментах тестирования на языке Python, но многие из идей и выводов можно распространить на другие языки программирования, поскольку подходы часто не зависят от конкретной технологии.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

В Python существует множество инструментов для написания тестов и выбор между ними неочевиден. Я опишу интересные варианты использования PyTest и расскажу о его [плюсах|минусах|неявных возможностях]. В статье вы найдёте развёрнутый пример использования Allure, который служит для создания простых и понятных отчётов автотестов. Также в примерах будет применяться фреймворк для написания матчеров — Hamcrest для Python. Надеюсь, что в итоге, те, кто сейчас в поиске инструментов для тестирования, смогут на основе изложенных примеров быстро внедрить функциональное тестирование в своем окружении. Те же, кто уже использует какой-то инструмент, смогут узнать новые подходы, варианты использования и концепции.

Исторически так сложилось, что в нашем проекте обитает целый зоопарк технологий со сложными схемами взаимодействий друг с другом. При этом их API и функциональность только растут, так что нужно реализовывать интеграционные тесты.

Нам как автоматизаторам для налаживания оптимального процесса тестирования необходим максимально удобный и гибкий инструмент для написания тестов. Python был выбран потому, что он прост в освоении, код на нём, как правило, легко читается, и, что самое важное, — у него есть богатая стандартная библиотека и масса пакетов расширений.

Посмотрев же на список инструментов для функционального тестирования, невольно впадаешь в ступор и задумываешься о том, какой инструмент все-таки выбрать, чтобы быстро писать тесты, не иметь проблем с их поддержкой и легко обучать работе с ним новых сотрудников.

В своё время была возможность поэкспериментировать, и выбор пал на перспективный фреймворк PyTest. Тогда он ещё не был таким популярным, и его мало кто использовал. Нам понравилась концепция использования фикстур и написание тестов в виде обычного Python-модуля без использования API. В итоге PyTest выстрелил, и теперь мы имеем очень гибкое решение с множеством фич, например:

Написание тестов

Фикстуры

В общепринятом смысле, фикстура — это фиксированное состояние стенда, на котором выполняются тесты. Это так же относится к действию, приводящему систему в определенное состояние.

В pytest фикстурой называют функцию, обёрнутую в декоратор @pytest.fixture. Сама функция выполняется в тот момент, когда она нужна (перед тестовым классом, модулем или функцией) и когда возвращенное ей значение доступно в самом тесте. При этом фикстуры могут использовать другие фикстуры, кроме того можно определять время существования конкретной фикстуры: в текущей сессии, модуле, классе или функции. Они помогают нам содержать тесты в модульном виде. А при тестировании интеграции повторно использовать их из соседних тестовых библиотек. Гибкость и удобство их использования были одними из основных критериев выбора именно pytest. Чтобы воспользоваться фикстурой, нужно указать её имя в качестве параметра к тесту.

Тестируемый сервер

Далее в примерах будут описаны тесты, которые проверяют функционал веб-сервера на Flask, ожидающий соединения на 8081 порту и принимающий GET запросы. Сервер берет строчку из параметра text и в ответе меняет каждое слово на его слово-перевертыш. Отдаётся json, если клиент умеет его принимать:

Напишем тест для тестируемого сервера, который будет проверять его наличие на указанном порту. Проверим, что наш сервер существует. Для этого воспользуемся модулем socket. Создадим фикстуру, которая подготовит сокет и после окончания теста его закроет.

Остерегайтесь использовать autouse фикстуры. Они опасны тем, что могут незаметно для вас изменить данные. Для гибкого их использования можно проверять наличие требуемой фикстуры для вызванного теста:

Матчеры

Например, следующий тест:

вернет развёрнутый ответ о том, где ошибка:

PyHamcrest позволяет совмещать встроенные в него матчеры. Скомбинировав таким образом has_property и contains_string, получим удобные для использования простые матчеры:

Про Hamcrest можно почитать на Хабре. Ещё стоит обратить внимание на should-dsl.

Параметризация

Когда требуется запускать один и тот же тест с множеством разных параметров, на помощь приходит параметризация тестовых данных. С помощью параметризации утилизируется повторяющийся код в тестах. Визуальное выделение списка параметров помогает повысить читаемость и дальнейшую поддержку. Фикстуры описывают систему, подготавливают её или приводят к требуемому состоянию. Параметризация же используется для формирования набора различных тестируемых параметров, описывающих тест-кейсы.

В таком отчете совершенно непонятно, какой параметр был использован в конкретном запуске.

Маркировка

С помощью маркировки можно пометить тест как вызывающий ошибку, пропустить тест, либо добавить user-defined метку. Всё это метаданные для группировки, либо пометки необходимых тестов, кейсов или параметров. В случае группировки мы используем эту возможность для указания severity к тестам и классам, так как есть более и менее важные тесты.

Выполнение и отладка

Запуск

Дополнительно хотелось бы отметить, что pytest умеет запускать UnitTest и nose тесты.

Отладка

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Анализ результатов

Результирующий отчет — это полученный набор данных об успешно пройденных, пропущенных и упавших тестах. Упавшие тесты должны описывать состояние системы, шаги, приводящие систему к такому результату, параметры, при которых тест упал, и что ожидалось от системы при использовании этих параметров. В отчете также может быть указано: на каком стенде запускались тесты, какие стенды являются целью, какая версия тестовой библиотеки используется, версии тестируемых сервисов и сопутствующих им приложений, что за тестпак: smoke или functional, какой тестовый файл был запущен. Понятное дело, что такие отчеты должны быть простые и понятные для чтения.

У pytest есть хороший генератор JUnit отчетов, который очень просто интегрируется в Jenkins-CI. Мы пользовались им, пока не появился замечательный фреймворк Allure, для формирования более красивых отчетов с дополнительными возможностями.

Step’ами можно сгруппировать действия, исполняемые в процессе теста, в отдельные блоки. Очень удобно их использовать в фикстурах, которые подготавливают стенд или меняют базу данных. Потом в отчете легко будет понять на какой стадии произошла ошибка и какие шаги были выполнены для данного тест-кейса.

Можно локально проверить, как это будет выглядеть на страничке, запустив следующие команды, если вы используете Ubuntu:

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytestallure passed with headers

Если вы открываете отчет локально и у вас в браузере только серое окно с иконками, то вам нужно поправить политику безопасности, так как allure использует javascript для отображения отчета.

В заключении расскажу вам, какие плагины мы используем постоянно, а какие только пробовали:

Кроме этого, существует хорошая документация для PyTest. Также советую вам посмотреть несколько статей про его использование.

Источник

PyTest

Предисловие

По историческому призванию я SQL-щик. Однако судьба занесла меня на BigData и после этого понесла кривая — я освоил и Java, и Python, и функциональное программирование (изучение Scala стоит в списке). Собственно на одном из кусков проекта встала необходимость тестирования кода на Python. Ребята из QA посоветовали для этих целей PyTest, но даже они затруднились толком ответить чем этот зверь хорош. К сожалению, в русскоязычном сегменте информации по данному вопросу не так уж и много: как это используют в Yandex да и все по-хорошему. При этом описанное в этой статье выглядит достаточно сложно для человека начинающего путешествие по этой стезе. Не говоря уже об официальной документации — она приобрела для меня смысл лишь после того, как я разобрался с самим модулем по другим источникам. Не спорю, там написаны интересные вещи, но, к сожалению, совсем не для старта.

Юнит-тестирование Python

Что это и для чего рассказывать смысла не вижу — Википедия все равно знает больше. По поводу существующих модулей для Python хорошо описано на Хабре.

Вводная по необходимым знаниям

На описываемый момент знания Python у меня были достаточно поверхностны — я писал кое-какие несложные модули и знал стандартные вещи. Но при столкновении с PyTest мне пришлось пополнять багаж знаний декораторами тут и тут и конструкцией yield.

Преимущества и недостатки PyTest

1) Независимость от API (no boilerplate). Как код выглядит в том же unittest:

То же самое в PyTest:

2) Подробный отчет. В том числе выгрузка в JUnitXML (для интеграции с Jenkins). Сам вид отчета может изменяться (включая цвета) дополнительными модулями (о них будет позднее отдельно). Ну и вообще цветной отчет в консоли выглядит удобнее — красные FAILED видны сразу.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

3) Удобный assert (стандартный из Python). Не приходится держать в голове всю кучу различных assert’ов.

4) Динамические фикстуры всех уровней, которые могут вызываться как автоматически, так и для конкретных тестов.

5) Дополнительные возможности фикстур (возвращаемое значение, финализаторы, область видимости, объект request, автоиспользование, вложенные фикстуры)

6) Параметризация тестов, то есть запуск одного и того же теста с разными наборами параметров. Вообще это относится к пункту 5 «Дополнительные возможности фикстур», но возможность настолько хороша, что достойна отдельного пункта.

7) Метки (marks), позволяющие пропустить любой тест, пометить тест, как падающий (и это его ожидаемое поведение, что полезно при разработке) или просто именовать набор тестов, чтобы можно было запускать только его по имени.

8) Плагины. Данный модуль имеет достаточно большой список дополнительных модулей, которые можно установить отдельно.

9) Возможность запуска тестов написанных на unittest и nose, то есть полная обратная совместимость с ними.

Про недостатки, пусть их и не много, могу сказать следующее:

1) Отсутствие дополнительного уровня вложенности: Для модулей, классов, методов, функций в тестах есть соответствующий уровень. Но логика требует наличие дополнительного уровня testcase, когда та же одна функция может иметь несколько testcase’ов (например, проверка возращаемых значений и ошибок). Это частично компенсируется дополнительным модулем (плагином) pytest-describe, но там встает проблема отсутствия соответствующего уровня фикстуры (scope = “describe”). С этим конечно можно жить, но в некоторых ситуациях может нарушать главный принцип PyTest — «все для простоты и удобства».

2) Необходимость отдельной установки модуля, в том числе в продакшене. Все-таки unittest и doctest входят в базовый инструментарий Python и не требуют дополнительных телодвижений.

3) Для использования PyTest требуется немного больше знаний Python, чем для того же unittest (см. «Вводная по необходимым знаниям»).

Подробное описание модуля и его возможностей под катом.

Запуск тестов

Базовые фикстуры

В данном случае фикстурами я называю функции и методы, которые запускаются для создания соответствующего окружения для теста. PyTest, как и unittest, имеет названия для фикстур всех уровней:

Данный пример достаточно полно показывает иерархию и повторяемость каждого уровня фикстур (например, setup_function вызывается перед каждым вызовом функции, а setup_module – только один раз для всего модуля). Также можно видеть, что уровень фикстуры по умолчанию — функция/метод (фикстура setup и teardown).

Расширенные фикстуры

Вопрос что делать, если для части тестов нужно определенное окружение, а для других нет? Разносить по разным модулям или классам? Не выглядит очень удобно и красиво. На помощь приходят расширенные фикстуры PyTest.

Итак, для создания расширенной фикстуры в PyTest необходимо:

1) импортировать модуль pytest
2) использовать декоратор @pytest.fixture(), чтобы обозначить что данная функция является фикстурой
3) задать уровень фикстуры (scope). Возможные значения “function”, “cls”, “module”, “session”. Значение по умолчанию = “function”.
4) если необходим вызов teardown для этой фикстуры, то надо добавить в него финализатор (через метод addfinalizer объекта request передаваемого в фикстуру или же через использование конструкции yield)
5) добавить имя данной фикстуры в список параметров функции

Вызов расширенных фикстур

Следует добавить, что расширенные фикстуры можно вызывать еще двумя способами:

1) декорирование теста декоратором @pytest.mark.usefixtures()
2) использование флага autouse для фикстуры. Однако следует использовать данную возможность с осторожностью, так как в итоге вы можете получить неожиданное поведение тестов.
3) собственно описанный выше способ через параметры теста

Вот так будет выглядеть предыдущий пример:

teardown расширенной фикстуры

Как было сказано выше, если необходим вызов teardown для определенной расширенной фикстуры, то можно реализовать его двумя способами:

1) добавив в фикстуру финализатор (через метод addfinalizer объекта request передаваемого в фикстуру
2) через использование конструкции yield (начиная с PyTest версии 2.4)

Первый способ мы рассмотрели в примере создания расширенной фикстуры. Теперь же просто продемонстрируем ту же самую функциональность через использование yield. Следует заметить, что для использования yield при декорировании функции, как фикстуры, необходимо использовать декоратор @pytest.yield_fixture(), а не @pytest.fixture():

Вывод не буду добавлять в текст в связи с тем, что он совпадает с вариантом с финализатором.

Возвращаемое фикстурой значение

Как возможность, фикстура в PyTest может возвращать что-нибудь в тест через return. Будь то какое-то значение состояние, так и объект (например, файл).

Уровень фикстуры (scope)

Уровень фикстуры может принимать следующие возможные значения “function”, “cls”, “module”, “session”. Значение по умолчанию = “function”.\

function – фикстура запускается для каждого теста
cls – фикстура запускается для каждого класса
module – фикстура запускается для каждого модуля
session – фикстура запускается для каждой сессии (то есть фактически один раз)

Например, в предыдущем примере можно поменять scope на function и вызывать подключение к базе данных и отключение для каждого теста:

Также фикстуры можно описывать в файле conftest.py, который автоматически импортируется PyTest. При этом фикстура может иметь любой уровень (только через описание в этом файле можно создать фикстуру с уровнем «сессия»).

Например, создадим отдельную папку session scope с файлом conftest.py и двумя файлами тестов (напомню, что чтобы PyTest автоматически импортировал модули их названия должны начинаться с test_. Хотя это поведение можно изменить.):

Объект request

В примере создания расширенной фикстуры мы передали в нее параметр request. Это было сделано чтобы через его метод addfinalizer добавить финализатор. Однако этот объект имеет также достаточно много атрибутов и других методов (полный список в официальном API).

Параметризация

Параметризация — это способ запустить один и тот же тест с разным набором входных параметров. Например, у нас есть функция, которая добавляет знак вопроса к строке, если она длиннее 5 символов, восклицательный знак — менее 5 символов и точку, если в строке ровно 5 символов. Соответственно вместо того, чтобы писать три теста, мы можем написать один, но вызываемый с разными параметрами.

Задать параметры для теста можно двумя способами:

1) Через значение параметра params фикстуры, в который нужно передать массив значений.
То есть фактически фикстура в данном случае представляет собой обертку, передающую параметры. А в сам тест они передаются через атрибут param объекта request, описанного выше.
2) Через декоратор (метку) @pytest.mark.parametrize, в который передается список названий переменных и массив их значений.

Итак первый способ.

Все отлично работает кроме одной неприятной детали — по названию теста невозможно понять, что за параметр был передан в тест. И в этом случае выручает параметр ids фикстуры. Он принимает или список имен тестов (его длина должна совпадать с количеством оных), или функцию, которая сгенерирует итоговое название.

В данном случае я запустил PyTest с дополнительным параметром —collect-only, который позволяет собрать все тесты, порожденные параметризацией, без их запуска.

Второй способ имеет одно преимущество: если указать несколько меток с разными параметрами, то в итоге тест будет запущен со всеми возможными наборами параметров (то есть декартово произведение параметров).

В метке параметризации также можно передать параметр ids, ответственный за отображение параметров в выводе аналогично первому способу задания параметров:

Вызов нескольких фикстур и фикстуры, использующие фикстуры

PyTest не ограничивает список фикстур вызываемый для теста.

Также любая фикстура может также вызывать к исполнению любое количество фикстур до себя:

Метки

PyTest поддерживает класс декораторов @pytest.mark называемый «метками» (marks). Базовый список включает в себя следующие метки:

1) @pytest.mark.parametrize — для параметризации тестов (было рассмотрено выше)
2) @pytest.mark.xfail – помечает, что тест должен не проходить и PyTest будет воспринимать это, как ожидаемое поведение (полезно, как временная метка для тестов на разрабатываемые функции). Также эта метка может принимать условие, при котором тест будет помечаться данной меткой.
3) @pytest.mark.skipif – позволяет задать условие при выполнении которогл тест будет пропущен
4) @pytest.mark.usefixtures – позволяет перечислить все фикстуры, вызываемые для теста

Также меткой можно пометить не только тест, но и класс, модуль (задается через изменение атрибута импортируемого модуля) или его запуск, получаемый через параметризацию (см. следующий пример).

Обработка исключений

Конечно же, как полноценный модуль для тестирования, PyTest также позволяет проверять корректность возвращаемых исключений при помощи «with pytest.raises()».

Запуск тестов по имени или ID

Интеграция с PyDev в Eclipse

Хотелось бы упомянуть, что PyTest интегрирован в компонент PyUnit модуля PyDev для Eclipse. Просто в настройках надо указать, что надо использовать именно его.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Дополнительные модули

PyTest имеет массу дополнительных модулей.
Могу лишь упомянуть те модули, которые меня заинтересовали и почему (детали о модулях можно прочитать по ссылке выше):

pytest-describe – добавляет еще один уровень абстракции (модуль-описание-функция, как эквивалент модуль-функция-testcase).

pytest-instafail – изменяет базовое поведение модуля таким образом что все ошибки и падения показываются в процессе исполнения, а не окончанию работы всей сесссии.

pytest-marks – позволяет задавать несколько меток одновременно для теста:

pytest-ordering — позволяет задавать вручную порядок запуска тестов через метку Run.

pytest-pep8 – позволяет проверять код тестов на соответствие соглашения pep-8.

pytest-smartcov — позволяет проверять покрытие кода тестам, как полное, так и частичное.

pytest-timeout — позволяет завершать тесты по таймауту, через параметр командной строки или специальной метки.

pytest-sugar — позволяет изменить внешний вид вывода PyTest’а, добавляя прогресс бар и процент выполнения. Выглядит красиво, пускай местами и не очень информативно.

Источник

Python Testing с pytest. ГЛАВА 3 pytest Fixtures

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytestВернуться Дальше что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Эта книга — недостающая глава, отсутствующая в каждой всеобъемлющей книге Python.

Frank Ruiz
Principal Site Reliability Engineer, Box, Inc.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Примеры в этой книге написаны с использованием Python 3.6 и pytest 3.2. pytest 3.2 поддерживает Python 2.6, 2.7 и Python 3.3+

Исходный код для проекта Tasks, а также для всех тестов, показанных в этой книге, доступен по ссылке на веб-странице книги в pragprog.com. Вам не нужно загружать исходный код, чтобы понять тестовый код; тестовый код представлен в удобной форме в примерах. Но что бы следовать вместе с задачами проекта, или адаптировать примеры тестирования для проверки своего собственного проекта (руки у вас развязаны!), вы должны перейти на веб-страницу книги и скачать работу. Там же, на веб-странице книги есть ссылка для сообщений errata и дискуссионный форум.

Под спойлером приведен список статей этой серии.

Теперь, когда вы познакомились с основами pytest, поглядим повнимательнее на фикстуры, которые необходимы для структурирования тестового кода практически для любой нетривиальной программной системы. Fixtures — это функции, выполняемые pytest до (а иногда и после) фактических тестовых функций. Код в фикстуре может делать все, что вам необходимо. Вы можете использовать Fixtures, чтобы получить набор данных для тестирования. Вы можете использовать Fixtures, чтобы получить систему в известном состоянии перед запуском теста. Fixtures также используются для получения данных для нескольких тестов.

Вот простой пример фикстуры, который возвращает число:

Декоратор @pytest.fixture() используется, чтобы сообщить pytest, что функция является фикстурой. Когда вы включаете имя фикстуры в список параметров тестовой функции, pytest знает, как запустить её перед запуском теста. Фикстуры могут выполнять работу, а могут возвращать данные в тестовую функцию.

Независимо от других смысловых значений, в pytest и в этой книге test fixtures относятся к механизму, который обеспечивает pytest, чтобы отделить код “подготовка к (getting ready for)” и “очистка после (cleaning up after)” от ваших тестовых функций.

pytest fixtures — одна из уникальных фишек, которые поднимают pytest над другими тестовыми средами, и являются причиной того, почему многие уважаемые люди переключаются на… и остаются с pytest. Тем не менее, фикстуры в pytest отличаются от фикстур в Django и отличаются от процедур setup и teardown, обнаруженных в unittest и nose. Есть много особенностей и нюансов если говорить о фикстурах. Как только вы получите хорошую ментальную модель того, как они работают, вам станет полегче. Тем не менее, вам нужно поиграться с ними некоторое время, чтобы въехать, поэтому давайте начнем.

Обмен Fixtures через conftest.py

Использование Fixtures вместо Setup и Teardown

К счастью, pytest включает в себя отличную фикстуру под названием tmpdir. Мы можем использовать её для тестирования и не должны беспокоиться о очистке. Это не магия, просто хорошая практика кодирования от самых пытливых людей. (Не переживайте; мы разберем tmpdir и более подробно распишем его с помощью tmpdir_factory в разделе «Использование tmpdir и tmpdir_factory» на стр. 71.)

С учетом всех этих составляющих, эта фикстура работает замечательно:

ch3/a/ tasks_proj /tests/conftest.py

Функция fixture запускается перед тестами, которые ее используют. Однако, если в функции есть yield, то там произойдёт остановка, контроль передастся тестам и выполняется следующая за yield строка после завершения тестов. Поэтому подумайте о коде над yield как о «setup», а о коде после yield как о «teardown». Код после yield «teardown» будет выполняться независимо от того, что происходит во время тестов. Мы не возвращаем данные с выходом в этомй фикстуре. Но вы можете.

Основное изменение здесь заключается в том, что дополнительная фикстура в файле была удалена, и мы добавили tasks_db в список параметров теста. Мне нравится структурировать тесты в форматеGIVEN/WHEN/THEN (ДАНО/КОГДА/ПОСЛЕ), используя комментарии, особенно если это не очевидно из кода, что происходит. Я думаю, что это полезно в этом случае. Надеюсь, GIVEN инициализированные задачи db помогут выяснить, почему tasks_db используется в качестве инструмента для теста.

Убедитесь, что Tasks установлен

Трассировка Fixture Execution с –setup-show

Если вы запустите тест из последнего раздела, вы не увидите, какие фикстуры запущены:

F и S перед именами фикстур указывают область. F для области действия и S для области сеанса. Я расскажу о сфере действия в разделе «Спецификация областей(Scope) Fixture» на стр. 56.

Использование Fixtures для Test Data

Fixtures являются отличным местом хранения данных для тестирования. Вы можете вернуть всё что угодно. Вот фикстура, возвращающая кортеж смешанного типа:

Поскольку test_a_tuple() должен завершиться неудачей (23! = 32), мы увидим, что произойдет, когда тест с фикстурой потерпит неудачу:

Вместе с разделом трассировки стека pytest отображает параметры значения функции, вызвавшей исключение или не прошедшей assert. В случае проведения тестов фикстуры — это параметры для теста, поэтому о них сообщается с помощью трассировки стека. Что произойдет, если assert (или exception) случиться в fixture?

Происходит пара вещей. Трассировка стека правильно показывает, что assert произошёл в функции фикстуры. Кроме того, test_other_data сообщается не как FAIL, а как ERROR. Это серьёзное различие. Если тест вдруг терпит неудачу, вы знаете, что сбой произошел в самом тесте, а не зависит от какой то фикстуры.

Но как насчет проекта Tasks? Для проекта Tasks мы, вероятно, могли бы использовать некоторые фикстуры данных, возможно, различные списки задач с различными свойствами:

ch3/a/tasks_proj/tests/conftest.py

Вы можете использовать их непосредственно из тестов, или из других фикстур. Давайте создадим с их помощью непустые базы данных для тестирования.

Использование Multiple Fixtures

Вы уже видели, что tmpdir использует tmpdir_factory. И вы использовали tmpdir в нашем task_db fixture. Давайте продолжим цепочку и добавим некоторые специализированные фикстуры для непустых баз проекта tasks:

ch3/a/tasks_proj/tests/conftest.py

Все эти fixtures включают две фикстуры в свой список параметров: tasks_db и набор данных. Набор данных используется для добавления задач в базу данных. Теперь тесты могут использовать их, если вы хотите, чтобы тест начинался с непустой базы данных, например:

ch3/a/tasks_proj/tests/func/test_add.py

Это также демонстрирует одну из главных причин использования fixtures: чтобы сфокусировать тест на том, что вы на самом деле тестируете, а не на том, что вы должны были сделать, чтобы подготовиться к тесту. Мне нравится использовать комментарии для GIVEN/WHEN/THEN и пытаться протолкнуть как можно больше данных (GIVEN) в фикстуры по двум причинам. Во-первых, это делает тест более читаемым и, следовательно, более ремонтопригодным. Во-вторых, assert или exception в фикстуре приводит к ошибке (ERROR), в то время как assert или exception в тестовой функции приводит к ошибке (FAIL). Я не хочу, чтобы test_add_increases_count() отказал, если инициализация базы данных завершилась неудачно. Это просто сбивает с толку. Я хочу, чтобы сбой (FAIL) test_add_increases_count() был возможен только в том случае, если add () действительно не смог изменить счетчик. Давайте запустим и посмотрим, как работают все фикстуры:

Получили снова кучу F-ов и S для функции и области сеанса. Давайте разберем, что это.

Спецификация областей(Scope) Fixture

Фикстуры включают в себя необязательный параметр под названием scope, который определяет, как часто фикстура получает setup и teardown. Параметр scope для @pytest.fixture() может иметь значения функции, класса, модуля или сессии. Scope по умолчанию — это функция. Настройки tasks_db и все фикстуры пока не определяют область. Таким образом, они являются функциональными фикстурами.

Ниже приведено краткое описание каждого значения Scope:

Выполняется один раз для каждой функции теста. Часть setup запускается перед каждым тестом с помощью fixture. Часть teardown запускается после каждого теста с использованием fixture. Это область используемая по умолчанию, если параметр scope не указан.

Выполняется один раз для каждого тестового класса, независимо от количества тестовых методов в классе.

Выполняется один раз для каждого модуля, независимо от того, сколько тестовых функций или методов или других фикстур при использовании модуля.

Выполняется один раз за сеанс. Все методы и функции тестирования, использующие фикстуру области сеанса, используют один вызов setup и teardown.

Вот как выглядят значения scope в действии:

Теперь вы можете видеть не только F и S для функции и сеанса, но также C и M для класса и модуля.

Область(scope) определяется с помощью фикстуры. Я знаю, что это очевидно из кода, но это важный момент, чтобы убедиться, что вы полностью грокаете (Прим переводчика: грокать — скорее всего автор имеет ввиду термин из романа Роберта Хайнлайна «Чужак в стране чужой». Приблизительное значение «глубоко и интуитивно понимать»). Область(scope) задается в определении фикстуры, а не в месте её вызова. Тестовые функции, которые используют фикстуру, не контролируют, как часто устанавливается(SETUP) и срывается(TEARDOWN) фикстура.

Фикстуры могут зависеть только от других фикстур из той же или более расширенной области(scope). Таким образом, function scope fixture может зависеть от других function scope fixture (по умолчанию и используется в проекте Tasks до сих пор). function scope fixture также может зависеть от класса, модуля и фикстур области сеанса, но в обратном порядке — никогда.

Смена Scope для Tasks Project Fixtures

С учетом этих знаний о scope, давайте теперь изменим область действия некоторых фикстур проекта Task.

До сих пор у нас не было проблем со временем тестирования. Но, согласитесь, что бесполезно создавать временный каталог и новое соединение с базой данных для каждого теста. Пока мы можем обеспечить пустую базу данных, когда это необходимо, этого должно быть достаточно.

ch3/b/tasks_proj/tests/conftest.py

Фикстуры данных просто возвращают значение, поэтому действительно нет причин, чтобы они работали все время. Один раз за сеанс достаточно:

ch3/b/tasks_proj/tests/conftest.py

Теперь давайте посмотрим, будут ли все эти изменения работать с нашими тестами:

Похоже, все в порядке. Давайте проследим фикстуры для одного тестового файла, чтобы увидеть, что различные области работают в соответствии с нашими ожиданиям:

Ага. Выглядит правильно. tasks_db_session вызывается один раз за сеанс, а более быстрый task_db теперь просто очищает базу данных перед каждым тестом.

Specifying Fixtures with usefixtures

Использование usefixtures почти то же самое, что указание имени фикстуры в списке параметров метода теста. Единственное отличие состоит в том, что тест может использовать возвращаемое значение фикстуры, только если оно указано в списке параметров. Тест, использующий фикстуру из-за использования usefixtures, не может использовать возвращаемое значение фикстуры.

Использование autouse для Fixtures That Always Get Used (которые используются непрерывно)

До сих пор в этой главе все фикстуры, используемые тестами, были обертками тестов (или использовали usefixtures для этого одного примера класса). Однако вы можете использовать autouse=True, чтобы фикстура работала постоянно. Это хорошо работает для кода, который вы хотите запустить в определенное время, но тесты на самом деле не зависят от состояния системы или данных из фикстуры. Вот довольно надуманный пример:

Тут мы демонстрируем добавление время тестирования после каждого теста, а также дату и текущее время в конце сеанса. Вот как всё это выглядит:

Функция autouse хорошо сработала. Но это скорее исключение, чем правило. Используйте фикстуры как декораторы, если у вас нет действительно большой причины не делать этого.

Теперь, когда вы видели autouse в действии, возможно вас интересует, почему мы не использовали его для tasks_db в этой главе. В проекте Tasks я чувствовал, что важно сохранить возможность проверить, что произойдет, если мы попытаемся использовать функцию API до инициализации БД. Это должно привести к соответствующему исключению. Но мы не сможем это проверить, если принудительно инициализировать каждый тест.

Переименование Fixtures

Название фикстур, перечисленные в списке параметров тестов и других фикстур, использующих их, обычно совпадает с именем функции фикстуры. Однако, pytest позволяет вам переименовывать фикстуры с параметром name в @pytest.fixture() :

ch3/ test_rename_fixture.py

Большая часть вывода не показана — там много чего. К счастью, фикстуры, которые мы определили, находятся внизу, вместе с тем, где они определены. Мы можем использовать это, чтобы найти определение lue. Давайте используем это в проекте «Tasks»:

Параметризация Фикстур

В [Parametrized Testing]Параметризованном тестировании, на стр. 42, мы параметризовали тесты. Мы также можем параметризовать фикстуры. Мы по-прежнему используем наш список задач, список идентификаторов задач и функцию эквивалентности, как и раньше:

Но теперь, вместо параметризации теста, мы параметризуем фикстуру под названием a_task :

ch3/b/tasks_proj/tests/func/ test_add_variety2.py

Элемент a_task довольно прост — он просто возвращает request.param в качестве значения для теста, используя его. Поскольку наш список задач состоит из четырех задач, фикстура будет вызываться четыре раза, а затем тест будет вызываться четыре раза:

Мы не предоставили идентификаторы, так pytest сам выдумал имена, добавив номер вызова(число) к имени фикстуры. Однако мы можем использовать тот же список строк, который мы использовали при параметризации наших тестов:

ch3/b/tasks_proj/tests/func/ test_add_variety2.py

Этот вариант дает нам идентификаторы получше:

Мы также можем установить параметр ids в функцию, которую мы пишем, которая предоставляет идентификаторы. Вот как это выглядит, когда мы используем функцию для генерации идентификаторов:

ch3/b/tasks_proj/tests/func/ test_add_variety2.py

Функция будет вызвана из значения каждого элемента из параметризации. Поскольку параметризация представляет собой список объектов Task, id_func() будет вызываться с объектом Task, что позволяет нам использовать методы доступа namedtuple для доступа к одному объекту Task для генерации идентификатора одного объекта Task за раз. Это немного чище, чем генерировать полный список раньше времени, и выглядит одинаково:

С параметризованными функциями вы можете запускать эту функцию несколько раз. Но с параметризованными фикстурами каждая тестовая функция, использующая эту фикстуру, будет вызываться несколько раз. И в этом сила, брат!

Параметризация Fixtures в Tasks Project

Теперь давайте посмотрим, как мы можем использовать параметризованные фикстуры в проекте Tasks. До сих пор мы использовали TinyDB для всех тестов. Но мы хотим, чтобы наши варианты оставались открытыми до конца проекта. Поэтому любой код, который мы пишем, и любые тесты, которые мы пишем, должны работать как с TinyDB, так и с MongoDB.

Решение (в коде), для которого используется база данных, изолируется от вызова start_tasks_db() в фикстуре tasks_db_session :

Параметр db_type в вызове start_tasks_db() не является магическим. Он просто завершает переключение на подсистему, которая отвечает за остальные взаимодействия с базой данных:

Чтобы протестировать MongoDB, нам нужно запустить все тесты с db_type равным mongo. Небольшая хитрость:

Здесь я добавил params=[‘tiny’,’ mongo’] в фикстуру-декоратор. Ещё добавил request в список параметров temp_db и установил db_type в request.param вместо того, чтобы просто выбрать «tiny» или «mongo».

Installing MongoDB

Чтобы отслеживать тестирование MongoDB, убедитесь, что установлены MongoDB и pymongo. Лично я тестировал с изданием сообщества MongoDB, найденным тут https://www.mongodb.com/download-center. pymongo установливается с pip—pip install pymongo. Однако использование MongoDB не обязательно поддерживать всю остальную часть книги; он используется в этом примере и в примере отладчика в Главе 7.

Вот что мы пока имеем:

Хм. Облом. Похоже, нам нужно будет изрядно отладиться, прежде чем мы позволим кому-либо использовать версию Mongo. Вы узнаете, как отладить это в pdb: Отладка тестовых сбоев, на стр. 125. До тех пор мы будем использовать версию TinyDB.

Упражнения

Что дальше

Реализация pytest fixture достаточно гибкая, чтобы использовать фикстуры, такие как building blocks, для создания тестового setup и teardown, а также для смены различных фрагментов системы (например, замена Mongo для TinyDB). Поскольку фикстуры настолько гибкие, я использую их в значительной степени, чтобы как можно больше настроить мои тесты на фикстуры.

В этой главе вы рассмотрели фикстуры pytest, которые пишете сами, а также пару встроенных(builtin) фикстур tmpdir и tmpdir_factory. В следующей главе вы подробно рассмотрите встроенные (builtin) фикстуры.

что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytestВернуться Дальше что такое фикстура pytest. Смотреть фото что такое фикстура pytest. Смотреть картинку что такое фикстура pytest. Картинка про что такое фикстура pytest. Фото что такое фикстура pytest

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *