Files
vibe_data_ana/tests/test_env_loader.py

256 lines
8.7 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.
"""环境变量加载器的单元测试。"""
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