Context сбрасывается с каждым новым сценарием в Behave

Всем привет! Имеется фреймворк для тестирования WEB UI на связке #behave + #selenium + #python + #pageobject . Вопрос прост донельзя: можно ли как то инициализировать context чтобы он не сбрасовал текущую страницу при новом сценарии?. Например:

Scenario1: tra ta ta
  Given I navigate to "homepage" page // Тут инициализируется context.page = HomePage(context.driver) и выполняется метод navigate()
...

Scenario2: ololo
  Given I log out from site

И тут при инициализации шага (context.page.logout()), если снова не определить текущую страницу вываливается эксепшен мол context не имеет никакого page. Если поставить эти шага в рамках одного сценария то все ок.
Кто сталкивался, подскажите, может есть сильные огрехи в проектировании, выложу схемку на всякий случай:

Контекст живет в рамках одной фичи. Все что вы запихаете туда, будет доступно во всех сценариях этой фичи. Ну и нужно больше кода :slight_smile: Плюс еще один важный момент, каждый сценарий должен быть изолирован от других и не влиять на их выполнение. Единственное что можно и нужно шарить между сценариями это driver, коннекшн к БД, SSH и т.п. дабы экономить время. Шарить открытую страницу между сценариями можно, только если вы не производите каких-то действий с ней, например проверяете текст, расположение элементов и т.п.
P.S.: контекст сам по себе не помирает. Скорее всего вы его чем то затираете.

видимо поэтому он и сбрасывает context.page. А как быть когда хочется сделать вот так:

  Scenario: 2.0 Registration page verification
    # Page elements verification
    Given I go to "register_page" page of site
    Then  I verify that current page contains its elements

    When  I push "register_button" button

  Scenario Outline: 2.1 Required fields verification
    Given I set "register_page" as current page  // Приходится вставлять этот костыль
    Then  I verify error tooltips for "<field_value>" field for "required_fields" config

    Examples: Fields
    | field_value          |
    | company_name_field*  |
    | company_email_field* |
    | first_name_field*    |
    | last_name_field*     |
    | email_field*         |
    | contact_phone_field* |
    | address_line1_field* |
    | country_field*       |

Получается я действую в рамках одной страницы а page при Scenario Outline уже сброшен и приходится его инициализировать при каждой линии. Это работает, но это не кошерно

Немного подумав я пришел к выводу что BasePage можно прокидывать в before_all чтобы шаровые методы были доступны, а для кастомных методов проверяемую страницу можно инициализировать отдельно

Передать страницу можно. Но повторюсь, это очень и очень плохая идея. Вы проверяете разные страницы и открытие страницы регистрации как прекондишн во 2м сценарии это правильный подход а не костыль. Почему When I push "register_button" button у вас идет после Then? Или это опечатка?

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

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

Да, изоляция тестов - это верный путь. А вот when после then, не по феншую так сказать. Тест должен состоять из 2х обязательных сущностей: действие и проверка и 2х не обязательных: setup и teardown. Ваще действие I push "register_button" button по сути является setup’ом для следующего теста. По этому его нужно и вынести в setup, дабы избавиться от зависимости между тестами.

В том то и дело, что я могу написать Then после When и будет так:

  Scenario: 2.0 Registration page verification
    # Page elements verification
    Given I go to "register_page" page of site
    Then  I verify that current page contains its elements

    When  I push "register_button" button
    Then  I verify error tooltips for "company_name_field*" field for "required_fields" config
    Then  I verify error tooltips for "company_email_field*" field for "required_fields" config
    ... 
    # И так все тултипы по порядку

Но хочется же использовать все возможности оформления шагов, ведь “Scenario Outline: 2.1” это просто шаг из целого сценария 2, оформленный по-другому, и туда приходится переопределять context.page. Вот если бы можно было отключить изоляцию на свой страх и риск - гибкости было бы больше

Ну у вас изначально не правильный подход к построению тестов. Вы делаете так называемую “портянку”, где куча действий и проверок. Behave и любой другой BDD фреймворк не подразумевает такого использования, да и это вообще в целом не хорошо. Если вкратце, то нужно стремиться к следующему виду тестов:
setup->действие->проверка->teardown, да в таком случае у вас будет больше тестов, но за то вы избавитесь от зависимостей, а так же точно будете знать что если упал тест А то значит что именно функциональность А работает не так как нужно. Это упрощает и разбор полетов и отладку\доработку тестов.
Проверок может быть много, но все они идут только после какого-то действия, тобишь вы изменяете начальное состояние системы каким-либо действием, и смотрите что система находится в предполагаемом состоянии. Проверка тоже по идее должна быть одна, но бывают исключения. Например если нужно проверить что на экране после создания нового пользователя появилось сообщение и соответственно что он прописался в БД. Но тут есть свой нюанс. Такие проверки лучше делать в soft assert. Чтобы если одна из проверок упала, то тест не завершался а проверял все условия. Для этого можно заюзать что-то вроде этого assertpy

Да, я с вами согласен, когда речь идет о functional тестах, то изоляция тестов - это необходимое условие. Но когда речь заходит о e2e тесте, где нужно применить модульное и интеграционное тестирование, то здесь без “портянки” не обойтись, все равно придется как то выкручиваться и выходить из общего стиля написания тестов

ок, я тогда вас не так понял. нужно было сразу написать, что вам нужно тестировать business flow. В таком случае, вам не очень подойдет Behave. Он больше для acceptance testing. Посмотрите в сторону Robot Framework

Спасибо большое, ознакомился, буду думать