Как стать автором
Обновить

Комментарии 9

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


В рабочем проекте мы достаточно продуктивно использовали RF, но потом всё равно с него съехали. Причин было несколько, и все их тут вряд ли получится описать. Самая главная — разработчики писали проект на Java, и хотели что-то более близкое по языку (выбрали Spock в итоге). Но своё дело он сделал, и опыт работы с ним до сих пор приятно вспомнить.


С другой стороны, лично я в своих Python-проектах последних лет однозначно делал выбор не в его пользу, а всегда брал pytest. Оправдано ли это? Надо подумать....

По-моему, эти два фреймворка некорректно сравнивать — pytest, это прежде всего более удобная замена юнит-тестам. И дело не в самом интерфейсе, а в том, что предполагается тестировать довольно низкоуровневые штуки. Хотя я не работал с robotics framework, насколько я понимаю, он заточен прежде всего для удобного описания пользовательского поведения во время тестирования (и порой, довольно сложного).
Что касается следующего:
В xUnit фреймворках есть аннотации, заменяющие настройки suite setup, а в Pytest есть фикстуры со scope=”class”.

В Pytest тест-кейсы могут быть просто методами (и тогда у них нет никакого suite setup — т.е. нет единой подготовки). Если же нужна единая подготовка, мы можем обернуть эти методы в класс. Но если мы сделаем фикстуру со scope=”class” для этого класса (т.е. попытаемся реализовать suite setup), то получим отдельный инстанс класса для каждого теста, так что данные из suite setup никак не попадут в тест-кейсы. Отдельные инстансы, вероятно, создаются из предположения, что данные из разных тест-кейсов не должны влиять друг для друга. Но из-за этого настроить среду для выполнения тестов намного сложнее, чем в Robot Framework, где suite setup предусмотрен априори.

То кажется, что вы просто не поняли суть scopes. Они нужны не для того, чтобы указать, на какие тесты выполнять сетап (связи scope и применимости фикстур нет), речь идет о том, что иногда нужно выполнять код, и кешировать результат (т.е. не выполнять этот код на каждый тест в классе). Применимость этой ситуации довольно ограниченная, т.к. по-умолчанию считается, что все инициализации для каждого теста нужно делать с чистого листа, но в некоторых ситуациях (типа создаем соединения со сторонним сервисом, или запускаем сервер), альтернативы нет. Именно для этого и нужно указывать scopes, на практике, я ни разу не использовать scope с уровнем класса, обычно или используется дефолтный scope функции, либо сразу всей сессии целиком.
Чтобы применить одну и ту же фикстуру на класс, можно воспользоваться декоратором
@pytest.mark.usefixtures("yourfixturename")
class TestClass(TestCase):
     pass

В этом случае, фикстура будет применена на все методы тесткейса, но инициализироваться она будет каждый раз с чистого листа. При этом, вовсе нет необходимости засовывать эти тест функции в класс в виде методов — с таким же успехом можно указать нужную фикстуру явно.
Если же, по каким-то причинам, явное указание не приемлемо (к примеру, потребуется отрефакторить сотню тестов), фикстуру можно применить автоматически внутри конкретного модуля, либо даже пакета:
@pytest.fixture(autouse=True)
def my_fixture():
    pass

В целом, чтобы понять парадигму pytest, нужно разобраться с возможностями фикстур, т.к. благодаря им, переиспользования кода выполняется при помощи композиции объектов, вместо наследования.
Теперь по поводу, чем же крут pytest, но сравнивать я буду с unittest интерфейсом (это будет более корректно).
Проблема тестовых классов в том, что setUp/tearDown порой становятся тяжелыми, и весь зоопарк объектов и моков запускается для всех тестовых методов класса:
Скрытый текст

Т.е., если у вас есть один маленький тестовый метод, для которого нужна половина этих объектов, все-равно будет вызван весь setUp и tearDown.
Pytest позволяет избежать этого, предлагая явно указывать только те фикстуры, которые нужны:
Скрытый текст

Если вы захотите переиспользовать setUp/tearDown между классами, то ситуация только усугубится, т.к. теперь вы будете создавать объекты из родительских классов:
Скрытый текст


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


При этом, вы можете указывать зависимости фикстур одной от другой, объединяя их в цепь:
Скрытый текст


Но самое крутое, что фикстуры могут не только генерировать тестовые объекты, но еще и мокать библиотеки, используя синтаксис генераторов. При этом, фикстура в себе включает, как setUp часть, так и tearDown:
Скрытый текст


Т.е. фикстуры представляют полноценную замену setUp/tearDown методам, при этом элегантно избегая проблемы божественного класса.
Есть еще и другие удобные плюшки в pytest, как параметрические тесты, локальные conftest конфигурации и плагины, но это уже больше детали.
В Pytest и ряде других xUnit фреймворков название тест-кейса всегда должно начинаться с test. Мне кажется логичным, когда используется метод test. Но в остальных случаях ограничения на наименования не помогают процессу.

Мне кажется эта идея довольно сомнительной, но если есть такая необходимость, то вы легко можете переопределить это поведение в конфигурации:
# content of pytest.ini
# Example 1: have pytest look for "check" instead of "test"
[pytest]
python_files = check_*.py
python_classes = Check
python_functions = *_check
Поскольку Pytest заточен под юнит-тестирование, реальные и тестовые методы приложения могут лежать в одном классе, так что возможна неразбериха.

Не должны! Тесты всегда лежат отдельно от кода. Но что касается pytest, то его интерфейс направлен на то, чтобы писать отдельные тестовые функции, а не классы. Поддержка классов нужна прежде всего для обратной совместимости с олдскульными юниттестами.
Сорян, что несколькими коментариями, так проще отвечать :)
pytest – это инструмент, который подходит для различных видов тестирования, а не только юнит. Благодаря расширяемой архитектуре на основе pluggy, он позволяет решать практически любые задачи. Если есть опыт работы с pytest, то считаю, что связка pytest + pytest-bdd + allure будет более сильной.

Пользовались на нескольких проектах когда-то роботом, совершенно не понравилось. Если мне память не изменяет, любой нетривиальный кейс превращался в нечитаемую портянку из текста на роботовском dsl и имплементации ключевых слов на питоне, между которыми приходилось постоянно переключаться. И нормальной поддержки в IDE тогда не было (сейчас может есть, не знаю).
Я так понимаю, что основная идея робота была в том, что тесты на нем смогут писать тестировщики, не умеющие писать код, но с нашими тестировщиками это явно не работало. Оказалось проще их обучить программированию.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий