| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- # -*- coding: utf-8 -*-
- """
- Tests für das Google Cloud TTS Plugin.
- """
- import pytest
- from pathlib import Path
- from unittest.mock import MagicMock, AsyncMock, patch
- import importlib.util
- # Plugin-main.py direkt laden
- plugin_path = Path(__file__).parent.parent / "main.py"
- spec = importlib.util.spec_from_file_location("google_tts_plugin", plugin_path)
- google_module = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(google_module)
- GoogleTTSPlugin = google_module.GoogleTTSPlugin
- GoogleTTSProvider = google_module.GoogleTTSProvider
- from trixy_core.audio.tts import TTSConfig, TTSState
- class TestGoogleTTSProvider:
- """Tests für den GoogleTTSProvider."""
- @pytest.fixture
- def provider(self, tmp_path):
- """Erstellt einen Provider für Tests."""
- config = TTSConfig(language="de-DE", voice_id="de-DE-Wavenet-C")
- return GoogleTTSProvider(
- config=config,
- credentials_path=None,
- voice_name="de-DE-Wavenet-C",
- speaking_rate=1.0,
- pitch=0.0,
- )
- def test_provider_name(self, provider):
- """Prüft den Provider-Namen."""
- assert provider.name == "google"
- def test_supported_languages(self, provider):
- """Prüft die unterstützten Sprachen."""
- languages = provider.supported_languages
- assert "de-DE" in languages
- assert "en-US" in languages
- assert "fr-FR" in languages
- assert "ja-JP" in languages
- def test_supports_streaming(self, provider):
- """Prüft, dass Streaming nicht unterstützt wird (simuliert)."""
- assert provider.supports_streaming is False
- def test_initial_state(self, provider):
- """Prüft den initialen Zustand."""
- assert provider._model_loaded is False
- assert provider._client is None
- assert len(provider._available_voices) == 0
- def test_speaking_rate_config(self, provider):
- """Prüft die Sprechrate-Konfiguration."""
- assert provider._speaking_rate == 1.0
- def test_pitch_config(self, provider):
- """Prüft die Tonhöhen-Konfiguration."""
- assert provider._pitch == 0.0
- @pytest.mark.asyncio
- async def test_synthesize_without_init_raises(self, provider):
- """Prüft, dass synthesize ohne Initialisierung fehlschlägt."""
- with pytest.raises(RuntimeError, match="Google TTS Client nicht initialisiert"):
- await provider.synthesize("Test")
- @pytest.mark.asyncio
- async def test_get_voices_returns_empty_before_init(self, provider):
- """Prüft, dass get_voices vor Initialisierung leer ist."""
- voices = await provider.get_voices()
- assert len(voices) == 0
- class TestGoogleTTSPlugin:
- """Tests für das GoogleTTSPlugin."""
- @pytest.fixture
- def plugin(self, mock_application, tmp_path):
- """Erstellt ein Plugin für Tests."""
- plugin_path = tmp_path / "tts_google"
- plugin_path.mkdir()
- config = {
- "name": "Google TTS",
- "enabled": True,
- "voice": "de-DE-Wavenet-C",
- "language": "de-DE",
- "speaking_rate": 1.0,
- "pitch": 0.0,
- }
- return GoogleTTSPlugin(mock_application, plugin_path, config)
- def test_plugin_initialization(self, plugin):
- """Prüft die Plugin-Initialisierung."""
- assert plugin._provider is None
- assert plugin.config.get("voice") == "de-DE-Wavenet-C"
- def test_plugin_path(self, plugin):
- """Prüft den Plugin-Pfad."""
- assert plugin.plugin_path.exists()
- @pytest.mark.asyncio
- async def test_on_unload_without_provider(self, plugin):
- """Prüft on_unload ohne initialisierten Provider."""
- await plugin.on_unload()
- assert plugin._provider is None
- class TestGoogleTTSVoiceNaming:
- """Tests für Google TTS Voice-Benennung."""
- def test_wavenet_voice_pattern(self):
- """Prüft das WaveNet-Voice-Benennungsschema."""
- voice_name = "de-DE-Wavenet-C"
- parts = voice_name.split("-")
- assert len(parts) == 4
- assert parts[0] == "de" # Sprache
- assert parts[1] == "DE" # Region
- assert parts[2] == "Wavenet" # Typ
- assert parts[3] == "C" # Variante
- def test_standard_voice_pattern(self):
- """Prüft das Standard-Voice-Benennungsschema."""
- voice_name = "de-DE-Standard-A"
- parts = voice_name.split("-")
- assert parts[2] == "Standard"
- # Integration Tests (benötigen Google Cloud Credentials)
- @pytest.mark.integration
- class TestGoogleTTSIntegration:
- """Integrationstests für Google TTS (benötigen Credentials)."""
- @pytest.fixture(autouse=True)
- def skip_if_not_installed(self):
- """Überspringt Tests wenn google-cloud-texttospeech nicht installiert ist."""
- pytest.importorskip("google.cloud.texttospeech", reason="google-cloud-texttospeech nicht installiert")
- @pytest.fixture
- def provider_with_credentials(self, tmp_path):
- """Erstellt einen Provider mit Credentials."""
- config = TTSConfig(language="de-DE", voice_id="de-DE-Wavenet-C")
- return GoogleTTSProvider(
- config=config,
- credentials_path=None, # Nutzt GOOGLE_APPLICATION_CREDENTIALS
- voice_name="de-DE-Wavenet-C",
- )
- @pytest.mark.asyncio
- @pytest.mark.slow
- async def test_full_synthesis_flow(self, provider_with_credentials):
- """Testet den vollständigen Synthese-Flow."""
- await provider_with_credentials.initialize()
- result = await provider_with_credentials.synthesize("Hallo Welt")
- assert result.audio_data is not None
- assert len(result.audio_data) > 0
- assert result.sample_rate == 24000
- assert result.duration_seconds > 0
- assert result.provider == "google"
- await provider_with_credentials.shutdown()
|