Files
xiaoxia-saas/tests/unit/test_tts_engine.py
T
CI Bot dcbb0f721e
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 20s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m20s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m45s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 30s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 20s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 56s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 29s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 35s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m10s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m45s
AI Code Review / AI Code Review (pull_request) Successful in 2m36s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m30s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m1s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
test(P3-1): 第56波 worker层更多引擎纯逻辑单测(+108)
- test_subtitle_render_engine.py: 53个(颜色转换/时间格式化/文字换行/ASS转义/样式)
- test_sticker_engine.py: 27个(配置类/位置解析/常量/便捷函数)
- test_tts_engine.py: 12个(数据类/入口判断/初始化)
- test_render_audio_utils.py: 16个(clip_effective_duration/RenderContext)

覆盖worker层4个模块的纯逻辑部分
2026-07-24 20:55:33 +08:00

132 lines
4.2 KiB
Python
Executable File
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.
"""
TTS 配音引擎数据类与纯逻辑测试.
覆盖 VoiceoverSegment / VoiceoverResult / TtsEngine 入口判断等纯逻辑.
TTS 合成调用依赖外部服务,由集成测试覆盖.
"""
from __future__ import annotations
from pathlib import Path
from unittest.mock import MagicMock
import pytest
from packages.domain.tts_config import TtsConfig
from video_processing.tts_engine import TtsEngine, VoiceoverResult, VoiceoverSegment
class TestVoiceoverSegment:
"""配音片段数据类."""
def test_default_values(self):
seg = VoiceoverSegment(text="hello")
assert seg.text == "hello"
assert seg.start_time == 0.0
assert seg.end_time == 0.0
assert seg.audio_path is None
assert seg.duration == 0.0
def test_full_values(self):
seg = VoiceoverSegment(
text="hello world",
start_time=1.5,
end_time=3.0,
audio_path=Path("/tmp/test.wav"),
duration=1.5,
)
assert seg.text == "hello world"
assert seg.start_time == 1.5
assert seg.end_time == 3.0
assert seg.audio_path == Path("/tmp/test.wav")
assert seg.duration == 1.5
def test_duration_calculation(self):
seg = VoiceoverSegment(text="test", start_time=0.0, end_time=5.5)
assert seg.end_time - seg.start_time == 5.5
class TestVoiceoverResult:
"""配音结果数据类."""
def test_default_failure(self):
result = VoiceoverResult()
assert result.success is False
assert result.segments == []
assert result.total_duration == 0.0
assert result.error_message == ""
def test_success_result(self):
segs = [
VoiceoverSegment(text="hello", duration=1.0),
VoiceoverSegment(text="world", duration=2.0),
]
result = VoiceoverResult(
success=True,
segments=segs,
total_duration=3.0,
)
assert result.success is True
assert len(result.segments) == 2
assert result.total_duration == 3.0
assert result.error_message == ""
def test_failure_with_message(self):
result = VoiceoverResult(success=False, error_message="TTS服务不可用")
assert result.success is False
assert result.error_message == "TTS服务不可用"
def test_segments_isolated_list(self):
"""确保每个实例有独立的segments列表."""
r1 = VoiceoverResult()
r2 = VoiceoverResult()
r1.segments.append(VoiceoverSegment(text="test"))
assert len(r2.segments) == 0
class TestTtsEngineInit:
"""TTS 引擎初始化."""
def test_init_creates_work_dir(self, tmp_path):
mock_tts = MagicMock()
work_dir = tmp_path / "tts_work"
engine = TtsEngine(mock_tts, work_dir)
assert work_dir.exists()
assert work_dir.is_dir()
def test_init_with_existing_dir(self, tmp_path):
mock_tts = MagicMock()
work_dir = tmp_path / "existing"
work_dir.mkdir()
engine = TtsEngine(mock_tts, work_dir)
assert work_dir.exists()
class TestTtsEngineEntryConditions:
"""TTS 引擎入口判断逻辑(不调用真实 TTS."""
def test_disabled_returns_failure(self, tmp_path):
mock_tts = MagicMock()
engine = TtsEngine(mock_tts, tmp_path)
config = TtsConfig(enabled=False, text="hello")
result = engine.generate_full_voiceover(config)
assert result.success is False
assert "未启用" in result.error_message or "空" in result.error_message
mock_tts.synthesize.assert_not_called()
def test_empty_text_returns_failure(self, tmp_path):
mock_tts = MagicMock()
engine = TtsEngine(mock_tts, tmp_path)
config = TtsConfig(enabled=True, text="")
result = engine.generate_full_voiceover(config)
assert result.success is False
mock_tts.synthesize.assert_not_called()
def test_whitespace_text_returns_failure(self, tmp_path):
mock_tts = MagicMock()
engine = TtsEngine(mock_tts, tmp_path)
config = TtsConfig(enabled=True, text=" ")
result = engine.generate_full_voiceover(config)
assert result.success is False
mock_tts.synthesize.assert_not_called()