Приспособление Pytest для запуска тестов запускается только один раз перед всеми тестами в классе - PullRequest
0 голосов
/ 03 мая 2018

Я тестирую функцию сообщений пользователя веб-решения с использованием pytest + selenium. Тесты сгенерируют тестовое сообщение для тестового пользователя, а затем войдут в систему этого пользователя, чтобы убедиться, что сообщение действительно отображается для этого пользователя.

  • Мне нужно генерировать эти сообщения через внутренний API.
  • Чтобы получить доступ к этому API, сначала нужно сгенерировать токен AUTH через другой API.

Итак, сценарий тестирования в основном:

  1. При запуске теста сгенерируйте новый токен AUTH с помощью вспомогательной функции API.
  2. Отправка запроса другому API для установки нового сообщения (требуется токен AUTH)
  3. Отправить запрос еще одному API, чтобы «сопоставить» это сообщение с указанным пользователем (требуется токен AUTH)
  4. Войдите в систему тестового пользователя и убедитесь, что новое сообщение действительно отображается.

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

Какое самое разумное решение для генерации одного нового токена доступа при вызове всех тестов?

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

import pytest
import helpers.api_access_token_helper as token_helper
import helpers.user_message_generator_api_helper as message_helper
import helpers.login_helper as login_helper
import helpers.popup_helper as popup_helper

class TestStuff(object):

    @pytest.yield_fixture(autouse=True)
    def run_around_tests(self):
        yield token_helper.get_api_access_token()

    def test_one(self, run_around_tests):
        auth_token = run_around_tests
        message_helper.create_new_message(auth_token, some_message_data)
        message_helper.map_message_to_user(auth_token, user_one["user_id"])
        login_helper.log_in_user(user_one["user_name"], user_one["user_password"])
        assert popup_helper.user_message_is_displaying(some_message_data["title"])

    def test_two(self, run_around_tests):
        auth_token = run_around_tests
        message_helper.create_new_message(auth_token, some_other_message_data)
        message_helper.map_message_to_user(auth_token, user_two["user_id"])
        login_helper.log_in_user(user_two["user_name"], user_two["user_password"])
        assert popup_helper.user_message_is_displaying(some_other_message_data["title"])

Я немного поработал с прибором "испытания на бегу", но не смог найти решение.

1 Ответ

0 голосов
/ 03 мая 2018

Необходимо адаптировать область действия прибора для кэширования его результатов для всех тестов в тестовом прогоне (scope='session'), всех тестов в модуле (scope='module'), всех тестов в классе (только для тестов в старом unittest стиле, scope='class') или для одного теста (scope='function'; это тест по умолчанию). Примеры:

функция приспособления

@pytest.fixture(scope='session')
def token():
    return token_helper.get_api_access_token()


class Tests(object):

    def test_one(self, token):
        ...

    def test_two(self, token):
        ...


class OtherTests(object):

    def test_one(self, token):
        ...

Токен будет вычислен один раз при первом запросе и будет храниться в кэше на протяжении всего выполнения теста, поэтому все три теста Tests::test_one, Tests::test_two и OtherTests::test_one будут иметь одинаковое значение токена.

метод класса прибора

Если вы намереваетесь писать тестовые классы старого стиля вместо тестовых функций и хотите, чтобы прибор был методом класса (как в вашем коде), обратите внимание, что вы можете использовать только область действия class, так что Значение крепежа распределяется только между тестами в классе:

class TestStuff(object):

    @pytest.fixture(scope='class')
    def token(self):
        return token_helper.get_api_access_token()

    def test_one(self, token):
        ...

    def test_two(self, token):
        ...

В сторону:

  1. pytest.yield_fixture устарело и заменено на pytest.fixture;
  2. вам не нужно устанавливать autouse=True, потому что вы явно запрашиваете прибор в параметрах теста. Это все равно будет называться.
...