Files
vibe_data_ana/tests/test_env_loader.py

256 lines
8.7 KiB
Python
Raw Normal View History

"""环境变量加载器的单元测试。"""
import os
import pytest
from pathlib import Path
from unittest.mock import patch
from src.env_loader import (
load_env_file,
load_env_with_fallback,
get_env,
get_env_bool,
get_env_int,
get_env_float,
validate_required_env_vars
)
class TestLoadEnvFile:
"""测试加载 .env 文件。"""
def test_load_env_file_success(self, tmp_path):
"""测试成功加载 .env 文件。"""
env_file = tmp_path / ".env"
env_file.write_text("""
# This is a comment
KEY1=value1
KEY2="value2"
KEY3='value3'
KEY4=value with spaces
# Another comment
KEY5=123
""", encoding='utf-8')
# 清空环境变量
with patch.dict(os.environ, {}, clear=True):
result = load_env_file(str(env_file))
assert result is True
assert os.getenv("KEY1") == "value1"
assert os.getenv("KEY2") == "value2"
assert os.getenv("KEY3") == "value3"
assert os.getenv("KEY4") == "value with spaces"
assert os.getenv("KEY5") == "123"
def test_load_env_file_not_found(self):
"""测试加载不存在的 .env 文件。"""
result = load_env_file("nonexistent.env")
assert result is False
def test_load_env_file_skip_existing(self, tmp_path):
"""测试跳过已存在的环境变量。"""
env_file = tmp_path / ".env"
env_file.write_text("KEY1=from_file\nKEY2=from_file")
# 设置一个已存在的环境变量
with patch.dict(os.environ, {"KEY1": "from_env"}, clear=True):
load_env_file(str(env_file))
# KEY1 应该保持原值(环境变量优先)
assert os.getenv("KEY1") == "from_env"
# KEY2 应该从文件加载
assert os.getenv("KEY2") == "from_file"
def test_load_env_file_skip_invalid_lines(self, tmp_path):
"""测试跳过无效行。"""
env_file = tmp_path / ".env"
env_file.write_text("""
VALID_KEY=valid_value
invalid line without equals
ANOTHER_VALID=another_value
""")
with patch.dict(os.environ, {}, clear=True):
result = load_env_file(str(env_file))
assert result is True
assert os.getenv("VALID_KEY") == "valid_value"
assert os.getenv("ANOTHER_VALID") == "another_value"
def test_load_env_file_empty_lines(self, tmp_path):
"""测试处理空行。"""
env_file = tmp_path / ".env"
env_file.write_text("""
KEY1=value1
KEY2=value2
KEY3=value3
""")
with patch.dict(os.environ, {}, clear=True):
result = load_env_file(str(env_file))
assert result is True
assert os.getenv("KEY1") == "value1"
assert os.getenv("KEY2") == "value2"
assert os.getenv("KEY3") == "value3"
class TestLoadEnvWithFallback:
"""测试按优先级加载多个 .env 文件。"""
def test_load_multiple_files(self, tmp_path):
"""测试加载多个文件。"""
env_file1 = tmp_path / ".env.local"
env_file1.write_text("KEY1=local\nKEY2=local")
env_file2 = tmp_path / ".env"
env_file2.write_text("KEY1=default\nKEY3=default")
with patch.dict(os.environ, {}, clear=True):
# 切换到临时目录
original_dir = os.getcwd()
os.chdir(tmp_path)
try:
result = load_env_with_fallback([".env.local", ".env"])
assert result is True
# KEY1 应该来自 .env.local优先级更高
assert os.getenv("KEY1") == "local"
# KEY2 应该来自 .env.local
assert os.getenv("KEY2") == "local"
# KEY3 应该来自 .env
assert os.getenv("KEY3") == "default"
finally:
os.chdir(original_dir)
def test_load_no_files_found(self):
"""测试没有找到任何文件。"""
result = load_env_with_fallback(["nonexistent1.env", "nonexistent2.env"])
assert result is False
class TestGetEnv:
"""测试获取环境变量。"""
def test_get_env_exists(self):
"""测试获取存在的环境变量。"""
with patch.dict(os.environ, {"TEST_KEY": "test_value"}):
assert get_env("TEST_KEY") == "test_value"
def test_get_env_not_exists(self):
"""测试获取不存在的环境变量。"""
with patch.dict(os.environ, {}, clear=True):
assert get_env("NONEXISTENT_KEY") is None
def test_get_env_with_default(self):
"""测试使用默认值。"""
with patch.dict(os.environ, {}, clear=True):
assert get_env("NONEXISTENT_KEY", "default") == "default"
class TestGetEnvBool:
"""测试获取布尔类型环境变量。"""
def test_get_env_bool_true_values(self):
"""测试 True 值。"""
true_values = ["true", "True", "TRUE", "yes", "Yes", "YES", "1", "on", "On", "ON"]
for value in true_values:
with patch.dict(os.environ, {"TEST_BOOL": value}):
assert get_env_bool("TEST_BOOL") is True
def test_get_env_bool_false_values(self):
"""测试 False 值。"""
false_values = ["false", "False", "FALSE", "no", "No", "NO", "0", "off", "Off", "OFF"]
for value in false_values:
with patch.dict(os.environ, {"TEST_BOOL": value}):
assert get_env_bool("TEST_BOOL") is False
def test_get_env_bool_default(self):
"""测试默认值。"""
with patch.dict(os.environ, {}, clear=True):
assert get_env_bool("NONEXISTENT_BOOL") is False
assert get_env_bool("NONEXISTENT_BOOL", True) is True
class TestGetEnvInt:
"""测试获取整数类型环境变量。"""
def test_get_env_int_valid(self):
"""测试有效的整数。"""
with patch.dict(os.environ, {"TEST_INT": "123"}):
assert get_env_int("TEST_INT") == 123
def test_get_env_int_negative(self):
"""测试负整数。"""
with patch.dict(os.environ, {"TEST_INT": "-456"}):
assert get_env_int("TEST_INT") == -456
def test_get_env_int_invalid(self):
"""测试无效的整数。"""
with patch.dict(os.environ, {"TEST_INT": "not_a_number"}):
assert get_env_int("TEST_INT") == 0
assert get_env_int("TEST_INT", 999) == 999
def test_get_env_int_default(self):
"""测试默认值。"""
with patch.dict(os.environ, {}, clear=True):
assert get_env_int("NONEXISTENT_INT") == 0
assert get_env_int("NONEXISTENT_INT", 42) == 42
class TestGetEnvFloat:
"""测试获取浮点数类型环境变量。"""
def test_get_env_float_valid(self):
"""测试有效的浮点数。"""
with patch.dict(os.environ, {"TEST_FLOAT": "3.14"}):
assert get_env_float("TEST_FLOAT") == 3.14
def test_get_env_float_negative(self):
"""测试负浮点数。"""
with patch.dict(os.environ, {"TEST_FLOAT": "-2.5"}):
assert get_env_float("TEST_FLOAT") == -2.5
def test_get_env_float_invalid(self):
"""测试无效的浮点数。"""
with patch.dict(os.environ, {"TEST_FLOAT": "not_a_number"}):
assert get_env_float("TEST_FLOAT") == 0.0
assert get_env_float("TEST_FLOAT", 9.99) == 9.99
def test_get_env_float_default(self):
"""测试默认值。"""
with patch.dict(os.environ, {}, clear=True):
assert get_env_float("NONEXISTENT_FLOAT") == 0.0
assert get_env_float("NONEXISTENT_FLOAT", 1.5) == 1.5
class TestValidateRequiredEnvVars:
"""测试验证必需的环境变量。"""
def test_validate_all_present(self):
"""测试所有必需的环境变量都存在。"""
with patch.dict(os.environ, {"KEY1": "value1", "KEY2": "value2", "KEY3": "value3"}):
assert validate_required_env_vars(["KEY1", "KEY2", "KEY3"]) is True
def test_validate_some_missing(self):
"""测试部分环境变量缺失。"""
with patch.dict(os.environ, {"KEY1": "value1"}, clear=True):
assert validate_required_env_vars(["KEY1", "KEY2", "KEY3"]) is False
def test_validate_all_missing(self):
"""测试所有环境变量都缺失。"""
with patch.dict(os.environ, {}, clear=True):
assert validate_required_env_vars(["KEY1", "KEY2"]) is False
def test_validate_empty_list(self):
"""测试空列表。"""
assert validate_required_env_vars([]) is True