0c84ec2cf6
- wechat_sync_use_case: 0% → 100%(14个测试) - jwt_handler: 45% → 100%(8个测试) - password_handler: 46% → 100%(6个测试) - job领域模型: 0% → 96%(53个测试) - quota配额系统: 0% → 100%(61个测试) - generation_task领域模型: 0% → 97%(50个测试) - feature_flags基础设施层: 0% → 100%(39个测试) - subtitle字幕领域模型: 0% → 98%(48个测试) - duplication查重记录: 0% → 100%(31个测试) - tts_config配音配置: 0% → 100%(35个测试) - edit_template剪辑模板: 0% → 93%(17个测试) - voice_clone_profile音色克隆: 0% → 95%(51个测试) 全量单元测试:3026 passed, 8 skipped(0失败) 新增测试用例约391个
199 lines
6.6 KiB
Python
Executable File
199 lines
6.6 KiB
Python
Executable File
"""
|
|
TTS 配音配置模型单元测试
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from packages.domain.tts_config import TtsConfig
|
|
|
|
|
|
class TestTtsConfigDefaults:
|
|
"""默认值测试"""
|
|
|
|
def test_default_values(self):
|
|
config = TtsConfig()
|
|
assert config.enabled is False
|
|
assert config.voice_id == ""
|
|
assert config.speed == 1.0
|
|
assert config.pitch == 0.0
|
|
assert config.volume == 0.8
|
|
assert config.text == ""
|
|
assert config.align_mode == "full"
|
|
assert config.overlap_mode == "replace"
|
|
|
|
|
|
class TestTtsConfigParse:
|
|
"""parse 方法测试"""
|
|
|
|
def test_parse_none(self):
|
|
config = TtsConfig.parse(None)
|
|
assert config.enabled is False
|
|
assert config.speed == 1.0
|
|
|
|
def test_parse_empty_dict(self):
|
|
config = TtsConfig.parse({})
|
|
assert config.enabled is False
|
|
|
|
def test_parse_not_dict(self):
|
|
config = TtsConfig.parse("not a dict")
|
|
assert config.enabled is False
|
|
|
|
def test_parse_disabled_returns_minimal(self):
|
|
"""disabled 时直接返回 enabled=False,忽略其他字段"""
|
|
config = TtsConfig.parse({
|
|
"enabled": False,
|
|
"voice_id": "v123",
|
|
"speed": 1.5,
|
|
})
|
|
assert config.enabled is False
|
|
assert config.voice_id == "" # 不保留
|
|
|
|
def test_parse_enabled_true(self):
|
|
config = TtsConfig.parse({
|
|
"enabled": True,
|
|
"voice_id": "voice_001",
|
|
"speed": 1.2,
|
|
"pitch": 2.5,
|
|
"volume": 0.5,
|
|
"text": "你好世界",
|
|
"align_mode": "subtitle",
|
|
"overlap_mode": "mix",
|
|
})
|
|
assert config.enabled is True
|
|
assert config.voice_id == "voice_001"
|
|
assert config.speed == 1.2
|
|
assert config.pitch == 2.5
|
|
assert config.volume == 0.5
|
|
assert config.text == "你好世界"
|
|
assert config.align_mode == "subtitle"
|
|
assert config.overlap_mode == "mix"
|
|
|
|
def test_parse_enabled_not_bool_false(self):
|
|
"""enabled 不是 bool 时视为 False"""
|
|
config = TtsConfig.parse({"enabled": "true"})
|
|
assert config.enabled is False
|
|
|
|
def test_parse_enabled_not_bool_zero(self):
|
|
config = TtsConfig.parse({"enabled": 0})
|
|
assert config.enabled is False
|
|
|
|
def test_parse_voice_id_not_string(self):
|
|
config = TtsConfig.parse({"enabled": True, "voice_id": 123})
|
|
assert config.voice_id == ""
|
|
|
|
def test_parse_speed_not_number(self):
|
|
config = TtsConfig.parse({"enabled": True, "speed": "fast"})
|
|
assert config.speed == 1.0
|
|
|
|
def test_parse_pitch_not_number(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": "high"})
|
|
assert config.pitch == 0.0
|
|
|
|
def test_parse_volume_not_number(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": "loud"})
|
|
assert config.volume == 0.8
|
|
|
|
def test_parse_text_not_string(self):
|
|
config = TtsConfig.parse({"enabled": True, "text": 12345})
|
|
assert config.text == ""
|
|
|
|
def test_parse_align_mode_invalid(self):
|
|
config = TtsConfig.parse({"enabled": True, "align_mode": "invalid"})
|
|
assert config.align_mode == "full"
|
|
|
|
def test_parse_align_mode_subtitle(self):
|
|
config = TtsConfig.parse({"enabled": True, "align_mode": "subtitle"})
|
|
assert config.align_mode == "subtitle"
|
|
|
|
def test_parse_align_mode_full(self):
|
|
config = TtsConfig.parse({"enabled": True, "align_mode": "full"})
|
|
assert config.align_mode == "full"
|
|
|
|
def test_parse_overlap_mode_invalid(self):
|
|
config = TtsConfig.parse({"enabled": True, "overlap_mode": "invalid"})
|
|
assert config.overlap_mode == "replace"
|
|
|
|
def test_parse_overlap_mode_replace(self):
|
|
config = TtsConfig.parse({"enabled": True, "overlap_mode": "replace"})
|
|
assert config.overlap_mode == "replace"
|
|
|
|
def test_parse_overlap_mode_mix(self):
|
|
config = TtsConfig.parse({"enabled": True, "overlap_mode": "mix"})
|
|
assert config.overlap_mode == "mix"
|
|
|
|
def test_parse_integer_speed(self):
|
|
"""int 类型的 speed 应该被转成 float"""
|
|
config = TtsConfig.parse({"enabled": True, "speed": 2})
|
|
assert config.speed == 2.0
|
|
assert isinstance(config.speed, float)
|
|
|
|
def test_parse_integer_pitch(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": -5})
|
|
assert config.pitch == -5.0
|
|
assert isinstance(config.pitch, float)
|
|
|
|
def test_parse_integer_volume(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": 1})
|
|
assert config.volume == 1.0
|
|
assert isinstance(config.volume, float)
|
|
|
|
|
|
class TestTtsConfigClamp:
|
|
"""边界钳制测试"""
|
|
|
|
def test_speed_too_low(self):
|
|
config = TtsConfig.parse({"enabled": True, "speed": 0.1})
|
|
assert config.speed == 0.5
|
|
|
|
def test_speed_too_high(self):
|
|
config = TtsConfig.parse({"enabled": True, "speed": 3.0})
|
|
assert config.speed == 2.0
|
|
|
|
def test_speed_lower_boundary(self):
|
|
config = TtsConfig.parse({"enabled": True, "speed": 0.5})
|
|
assert config.speed == 0.5
|
|
|
|
def test_speed_upper_boundary(self):
|
|
config = TtsConfig.parse({"enabled": True, "speed": 2.0})
|
|
assert config.speed == 2.0
|
|
|
|
def test_pitch_too_low(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": -20})
|
|
assert config.pitch == -12
|
|
|
|
def test_pitch_too_high(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": 20})
|
|
assert config.pitch == 12
|
|
|
|
def test_pitch_lower_boundary(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": -12})
|
|
assert config.pitch == -12
|
|
|
|
def test_pitch_upper_boundary(self):
|
|
config = TtsConfig.parse({"enabled": True, "pitch": 12})
|
|
assert config.pitch == 12
|
|
|
|
def test_volume_negative(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": -0.5})
|
|
assert config.volume == 0.0
|
|
|
|
def test_volume_over_one(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": 1.5})
|
|
assert config.volume == 1.0
|
|
|
|
def test_volume_zero(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": 0.0})
|
|
assert config.volume == 0.0
|
|
|
|
def test_volume_one(self):
|
|
config = TtsConfig.parse({"enabled": True, "volume": 1.0})
|
|
assert config.volume == 1.0
|
|
|
|
def test_clamp_via_direct_construction(self):
|
|
"""直接构造也应该钳制(通过 _clamp 方法)"""
|
|
config = TtsConfig(enabled=True, speed=5.0, pitch=100, volume=-1)
|
|
config._clamp()
|
|
assert config.speed == 2.0
|
|
assert config.pitch == 12
|
|
assert config.volume == 0.0
|