Files
Neo-ZQYY/tests/test_property_config_priority.py

73 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
配置优先级属性测试
**Validates: Requirements 4.3**
Property 3: 配置优先级 - .env.local 覆盖
对于任意配置项名称和两个不同的值,当根 .env 和应用 .env.local
都定义了该配置项时,配置加载器返回的值应等于 .env.local 中的值。
测试逻辑:
1. 使用 hypothesis 生成随机配置项名称(字母数字下划线)和两个不同的值
2. 创建临时 .env 文件,写入 KEY=value1
3. 创建临时 .env.local 文件,写入 KEY=value2
4. 使用 python-dotenv 模拟分层加载(先加载 .env再加载 .env.localoverride=True
5. 验证最终值等于 value2.env.local 的值)
不依赖 ETL 的 AppConfig直接测试 python-dotenv 的分层加载行为,
因为这是设计文档中描述的配置隔离机制的基础。
"""
import os
import tempfile
from hypothesis import given, settings, assume
from hypothesis.strategies import from_regex
from dotenv import dotenv_values
# 策略:生成合法的 .env 配置项名称和值
# 配置项名称:首字符为大写字母,后跟大写字母/数字/下划线
_key_strategy = from_regex(r"[A-Z][A-Z0-9_]{0,29}", fullmatch=True)
# 配置项值:可打印 ASCII排除换行、# 号(注释符)和引号(避免解析歧义)
_value_strategy = from_regex(r"[A-Za-z0-9_./:@\-]{1,50}", fullmatch=True)
@given(key=_key_strategy, val_root=_value_strategy, val_local=_value_strategy)
@settings(max_examples=100)
def test_env_local_overrides_root_env(key: str, val_root: str, val_local: str):
"""
Property 3: 配置优先级 - .env.local 覆盖
当根 .env 和应用 .env.local 都定义了同一配置项时,
分层加载(先 .env再 .env.local override=True的结果
应等于 .env.local 中的值。
**Validates: Requirements 4.3**
"""
# 两个值必须不同,否则无法验证覆盖语义
assume(val_root != val_local)
with tempfile.TemporaryDirectory() as tmpdir:
root_env = os.path.join(tmpdir, ".env")
local_env = os.path.join(tmpdir, ".env.local")
# 写入根 .env公共配置
with open(root_env, "w", encoding="utf-8") as f:
f.write(f"{key}={val_root}\n")
# 写入应用 .env.local私有覆盖
with open(local_env, "w", encoding="utf-8") as f:
f.write(f"{key}={val_local}\n")
# 模拟分层加载:先加载 .env再用 .env.local 覆盖
config = dotenv_values(root_env)
local_config = dotenv_values(local_env)
config.update(local_config) # .env.local 覆盖 .env
assert config[key] == val_local, (
f"配置项 '{key}' 应被 .env.local 覆盖为 '{val_local}'"
f"但实际值为 '{config[key]}'(根 .env 值: '{val_root}'"
)