Environment — это глобальная или локальная переменная?

Ответ

Переменные окружения (Environment Variables) могут быть как глобальными (системными), так и локальными (процессными), в зависимости от контекста их определения и области видимости.

  1. Глобальные (системные) переменные окружения:

    • Устанавливаются на уровне операционной системы (например, через setx в Windows или export в .bashrc/.zshrc в Linux/macOS).
    • Доступны всем процессам и пользовательским сессиям в системе.
    • Пример: PATH, JAVA_HOME, HOME.
  2. Локальные (процессные) переменные окружения:

    • Устанавливаются для конкретного процесса или сессии (например, в терминале или скрипте).
    • Видны только этому процессу и его дочерним процессам.
    • Пример: Переменные, заданные перед запуском команды в терминале (API_URL=test.com python test.py) или внутри скрипта/теста.

Практическое применение в тестировании:

  • Управление конфигурацией: Разделение настроек для разных сред (dev, staging, prod) через переменные.
  • Хранение секретов: Ключи API, пароли к базам данных (никогда не хранятся в коде!).
  • Параметризация тестов: Указание URL тестового сервера, времени ожидания и т.д.

Пример работы с переменными окружения в Python-тестах:

import os

# Установка локальной переменной для текущего процесса (например, в setUp)
os.environ["TEST_ENVIRONMENT"] = "STAGING"
os.environ["DB_TIMEOUT"] = "30"

# Чтение переменной окружения с значением по умолчанию
db_host = os.getenv("DATABASE_HOST", "localhost")  # Если переменной нет, вернётся 'localhost'
test_env = os.getenv("TEST_ENVIRONMENT")

# Использование в тесте для условного выполнения
def test_payment_gateway():
    if os.getenv("TEST_ENVIRONMENT") == "STAGING":
        # Выполнить тесты только на staging-среде
        response = call_staging_payment_api()
        assert response.status_code == 200
    else:
        pytest.skip("Test runs only in STAGING environment")

В CI/CD (Jenkins, GitLab CI, GitHub Actions): Переменные окружения — это основной способ передачи конфиденциальных данных (секретов) и параметров сборки в пайплайн тестирования. Они настраиваются в интерфейсе CI-системы и безопасно передаются в скрипты.

Ответ 18+ 🔞

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

Глобальные (системные) — это общие шкафчики в коридоре.
Их поставил администратор, и любой, кто зашёл в здание, может туда заглянуть. PATH, JAVA_HOME — вот это всё. Установил один раз через setx или в .bashrc, и теперь они торчат, как шишка, всем процессам на виду. Удобно, но если туда положить ключи от квартиры, где деньги лежат, то это пиздец как небезопасно.

Локальные (процессные) — это твой личный шкафчик в кабинке.
Ты его взял, когда пришёл, положил свои трусы и полотенце, и видит их только твой процесс и его дети (дочерние процессы). Закрыл кабинку — и нихуя никому не видно. Например, запускаешь команду в терминале: API_KEY=secret python script.py. Этот API_KEY — только для этого питона и его потомков. Вышел из процесса — и переменная накрылась медным тазом, её нет.

Зачем это всё в тестах, спросишь?
А затем, чувак, чтобы не быть распиздяем.

  • Управление конфигурацией: Один и тот же код может работать с DEV, STAGING и PROD. Меняешь одну переменную ENVIRONMENT — и всё, тесты бегут на нужной среде. Волнение ебать — минимальное.
  • Секреты: Ты что, будешь пароли от продакшн-базы в код пихать? Да ты с ума сошёл! Это же чих-пых тебя в сраку, если такой код в git утечёт. Секреты держим в переменных окружения CI-системы.
  • Параметризация: Хочешь, чтобы тесты ждали ответа 10 секунд на твоём древнем ноуте и 2 секунды на мощном сервере? Выноси таймаут в переменную TIMEOUT. Гибкость — овердохуища.

Смотри, как в Python с этим работать (код не трогаю, он и так норм):

import os

# Установка локальной переменной прямо в процессе (типа в setUp)
os.environ["TEST_ENVIRONMENT"] = "STAGING"
os.environ["DB_TIMEOUT"] = "30"

# Чтение переменной. Второй аргумент — значение по умолчанию, если переменной нет.
# Это спасает от ошибок, когда что-то не задали. Доверия ебать ноль к окружению, поэтому подстраховываемся.
db_host = os.getenv("DATABASE_HOST", "localhost")
test_env = os.getenv("TEST_ENVIRONMENT")

# Использование в тесте для условного выполнения
def test_payment_gateway():
    if os.getenv("TEST_ENVIRONMENT") == "STAGING":
        # Тестируем только на стейджинге, ибо на проде трогать платежи — это **сам от себя охуел**.
        response = call_staging_payment_api()
        assert response.status_code == 200
    else:
        pytest.skip("Test runs only in STAGING environment") # Пропускаем, если не стейджинг

Про CI/CD (Jenkins, GitLab, GitHub Actions):
Это святая святых. В интерфейсе этих систем настраиваешь переменные (особенно секретные), и они в рот мне чих-пых безопасно передаются в пайплайн. Ни в логах не светятся, ни в коде не торчат. Просто идешь в настройки, добавляешь PROD_DB_PASSWORD, и в скрипте он доступен как обычная переменная окружения. Красота, а не жизнь.

Короче, суть в чём: глобальные — для всех, локальные — для себя. В тестах используешь, чтобы не хардкодить конфиги и секреты. А в CI — это вообще must have, если не хочешь потом ебушки-воробушки искать, куда слились твои продовые ключи. Всё просто.