Skip to content

Commit f3cba23

Browse files
정연승정연승
authored andcommitted
[#17][AI] config + exceptions 단위 테스트 추가
1 parent b750ed1 commit f3cba23

3 files changed

Lines changed: 117 additions & 0 deletions

File tree

ai/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# ai/tests

ai/tests/test_config.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""ai/config.py 단위 테스트."""
2+
3+
import os
4+
5+
import pytest
6+
7+
from ai.config import AISettings
8+
9+
10+
class TestAISettings:
11+
"""AISettings 환경 변수 로드 및 기본값 테스트."""
12+
13+
def test_default_values(self):
14+
settings = AISettings(_env_file=None)
15+
assert settings.AWS_REGION == "ap-northeast-2"
16+
assert settings.MODEL_ID == "anthropic.claude-3-5-sonnet-20241022-v2:0"
17+
assert settings.KB_A_ID == ""
18+
assert settings.KB_B_ID == ""
19+
assert settings.MAX_TOKENS == 4096
20+
assert settings.TEMPERATURE == 0.7
21+
22+
def test_env_override(self, monkeypatch):
23+
monkeypatch.setenv("AWS_REGION", "us-east-1")
24+
monkeypatch.setenv("MODEL_ID", "anthropic.claude-3-haiku-20240307-v1:0")
25+
monkeypatch.setenv("KB_A_ID", "kb-a-123")
26+
monkeypatch.setenv("KB_B_ID", "kb-b-456")
27+
monkeypatch.setenv("MAX_TOKENS", "2048")
28+
monkeypatch.setenv("TEMPERATURE", "0.3")
29+
30+
settings = AISettings(_env_file=None)
31+
assert settings.AWS_REGION == "us-east-1"
32+
assert settings.MODEL_ID == "anthropic.claude-3-haiku-20240307-v1:0"
33+
assert settings.KB_A_ID == "kb-a-123"
34+
assert settings.KB_B_ID == "kb-b-456"
35+
assert settings.MAX_TOKENS == 2048
36+
assert settings.TEMPERATURE == pytest.approx(0.3)
37+
38+
def test_partial_env_override(self, monkeypatch):
39+
monkeypatch.setenv("KB_A_ID", "kb-only-a")
40+
settings = AISettings(_env_file=None)
41+
assert settings.KB_A_ID == "kb-only-a"
42+
assert settings.KB_B_ID == "" # default preserved

ai/tests/test_exceptions.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""ai/exceptions.py 단위 테스트."""
2+
3+
import pytest
4+
5+
from ai.exceptions import (
6+
AIError,
7+
AIErrorCode,
8+
AIGenerationFailedError,
9+
BedrockAPIError,
10+
PromptTemplateNotFoundError,
11+
RAGSearchFailedError,
12+
SchemaValidationError,
13+
)
14+
15+
16+
class TestAIErrorCode:
17+
"""AIErrorCode enum 테스트."""
18+
19+
def test_all_codes_exist(self):
20+
codes = {e.value for e in AIErrorCode}
21+
assert codes == {
22+
"AI_GENERATION_FAILED",
23+
"SCHEMA_VALIDATION_ERROR",
24+
"RAG_SEARCH_FAILED",
25+
"PROMPT_TEMPLATE_NOT_FOUND",
26+
"BEDROCK_API_ERROR",
27+
}
28+
29+
def test_is_str_enum(self):
30+
assert isinstance(AIErrorCode.AI_GENERATION_FAILED, str)
31+
32+
33+
class TestAIError:
34+
"""AIError 기반 클래스 테스트."""
35+
36+
def test_base_error_attributes(self):
37+
err = AIError(AIErrorCode.BEDROCK_API_ERROR, "test msg", {"key": "val"})
38+
assert err.code == AIErrorCode.BEDROCK_API_ERROR
39+
assert err.message == "test msg"
40+
assert err.details == {"key": "val"}
41+
assert "[BEDROCK_API_ERROR] test msg" in str(err)
42+
43+
def test_details_default_empty_dict(self):
44+
err = AIError(AIErrorCode.RAG_SEARCH_FAILED, "msg")
45+
assert err.details == {}
46+
47+
48+
class TestConcreteExceptions:
49+
"""각 커스텀 예외 클래스 테스트."""
50+
51+
@pytest.mark.parametrize(
52+
"exc_cls,expected_code",
53+
[
54+
(AIGenerationFailedError, AIErrorCode.AI_GENERATION_FAILED),
55+
(SchemaValidationError, AIErrorCode.SCHEMA_VALIDATION_ERROR),
56+
(RAGSearchFailedError, AIErrorCode.RAG_SEARCH_FAILED),
57+
(PromptTemplateNotFoundError, AIErrorCode.PROMPT_TEMPLATE_NOT_FOUND),
58+
(BedrockAPIError, AIErrorCode.BEDROCK_API_ERROR),
59+
],
60+
)
61+
def test_default_message_and_code(self, exc_cls, expected_code):
62+
err = exc_cls()
63+
assert err.code == expected_code
64+
assert isinstance(err, AIError)
65+
assert err.message # non-empty default message
66+
67+
def test_custom_message_and_details(self):
68+
err = BedrockAPIError("timeout occurred", details={"model_id": "claude-3"})
69+
assert err.message == "timeout occurred"
70+
assert err.details["model_id"] == "claude-3"
71+
72+
def test_exceptions_are_catchable_as_base(self):
73+
with pytest.raises(AIError):
74+
raise SchemaValidationError("bad schema")

0 commit comments

Comments
 (0)