Home | RU | EN

Конфигурации

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

package common.configs;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Config {
    private static final Config INSTANCE = new Config();
    
    private final Properties properties = new Properties();

    private Config() {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("config.properties")) {
            if (inputStream == null) {
                throw new RuntimeException("config.properties is not found in resources");
            }
            properties.load(inputStream);
        } catch (IOException e) {
            throw new RuntimeException("Fail to load config.properties", e);
        }
    }

    public static String getProperty(String key) {
        String systemValue = System.getProperty(key);
        if (systemValue != null) return systemValue;

        String envKey = key.toUpperCase().replace(".", "_")Строка String envKey = key.toUpperCase().replace(".", "_"); нужна для того, чтобы преобразовать ключ из config.properties (например, admin.password) в формат, принятый для переменных окружения в ОС (например, ADMIN_PASSWORD).

Почему так делается:

В config.properties ключи обычно пишут в "Java-стиле" через точки:
admin.password=1234
db.url=jdbc:postgresql://localhost:5432/test

В переменных окружения в Unix/Windows обычно используют верхний регистр и _ вместо точек:
ADMIN_PASSWORD=1234
DB_URL=jdbc:postgresql://localhost:5432/test

Поэтому метод и делает трансформацию:
key.toUpperCase() → admin.password → ADMIN.PASSWORD
.replace(".", "_") → ADMIN_PASSWORD

Таким образом у тебя появляется единая логика поиска значения:
сначала берём из System.getProperty("admin.password") (например, если ты передал -Dadmin.password=1234 при запуске Java),
если нет - пробуем из System.getenv("ADMIN_PASSWORD"),
если и там нет - берём из config.properties.;
        String envValue = System.getenv(envKey);
        if (envValue != null) return envValue;

        return INSTANCE.properties.getProperty(key);
    }
}

Объяснение кода

Класс Config реализует паттерн Singleton для централизованного управления конфигурацией приложения. Основные возможности:

Система приоритетов конфигурации

Метод getProperty() реализует систему приоритетов (от высшего к низшему):

  1. Системные свойства Java (System.getProperty) - передаются через -D параметры при запуске JVM. Это удобно для запуска тестов или jar’ника напрямую, когда ты хочешь быстро подменить значение (например, на другой URL).
  2. Переменные окружения (System.getenv) - устанавливаются в ОС, контейнере или CI/CD пайплане
  3. Файл config.properties - стандартный способ для локальной разработки

Примеры использования приоритетов конфигурации

1. Системные свойства

mvn clean test -DapiBaseUrl=http://localhost

2. Переменные окружения

Для Docker:

services:
  backend:
    image: nobugsme/nbank:with_database
    environment:
      - APIBASEURL=http://localhost:4111
      - UIBASEURL=http://localhost:80
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=admin123

Для CI/CD пайплайна:

- name: Run tests
  run: ./mvnw clean test -q
  env:
     UIREMOTE: http://localhost:4444/wd/hub
     APIBASEURL: http://194.87.199.75:4111
     UIBASEURL: http://194.87.199.75:80

Для ОС:

# Windows (PowerShell)
$env:APIBASEURL="http://localhost:3000"
$env:ADMIN_USERNAME="admin"
$env:ADMIN_PASSWORD="admin123"

# Linux/macOS (Bash)
export APIBASEURL=http://localhost:3000
export ADMIN_USERNAME=admin
export ADMIN_PASSWORD=admin123

3. Файл config.properties

apiBaseUrl=http://localhost:3000
admin.username=admin
admin.password=admin123

Шаги реализации:

  1. Создать пакет common/configs в структуре фреймворка
  2. Создать в нем класс Config.java с содержимым из примера
  3. Создать файл config.properties в папке src/main/resources (пример прилагается)
  4. Добавить в тесты метод Config.getProperty(), в места где надо достать переменные из файла config.properties (пример прилагается)

Пример config.properties:

# API Configuration
apiBaseUrl=http://localhost:4111
uiBaseUrl=http://localhost
apiVersion=/api/v1

# Browser Configuration
browser=chrome
browserSize=1920x1080

# Admin Credentials
admin.username=admin
admin.password=admin

# Selenoid Configuration
uiRemote=http://localhost:4444/wd/hub

# Database Configuration
db.url=jdbc:postgresql://localhost:5433/nbank
db.username=postgres
db.password=postgres
db.driver=org.postgresql.Driver
db.table.customers=customers

Пример использования в тестах:

public class BaseUiTest extends BaseApiTest {
    @BeforeAll
    static void globalSelenideSetup() {
        Configuration.remote = Config.getProperty("uiRemote");
        Configuration.baseUrl = Config.getProperty("uiBaseUrl");
        Configuration.browser = Config.getProperty("browser");
        Configuration.browserSize = Config.getProperty("browserSize");
        // и так далее...
    }
}