test_google_tts.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests für das Google Cloud TTS Plugin.
  4. """
  5. import pytest
  6. from pathlib import Path
  7. from unittest.mock import MagicMock, AsyncMock, patch
  8. import importlib.util
  9. # Plugin-main.py direkt laden
  10. plugin_path = Path(__file__).parent.parent / "main.py"
  11. spec = importlib.util.spec_from_file_location("google_tts_plugin", plugin_path)
  12. google_module = importlib.util.module_from_spec(spec)
  13. spec.loader.exec_module(google_module)
  14. GoogleTTSPlugin = google_module.GoogleTTSPlugin
  15. GoogleTTSProvider = google_module.GoogleTTSProvider
  16. from trixy_core.audio.tts import TTSConfig, TTSState
  17. class TestGoogleTTSProvider:
  18. """Tests für den GoogleTTSProvider."""
  19. @pytest.fixture
  20. def provider(self, tmp_path):
  21. """Erstellt einen Provider für Tests."""
  22. config = TTSConfig(language="de-DE", voice_id="de-DE-Wavenet-C")
  23. return GoogleTTSProvider(
  24. config=config,
  25. credentials_path=None,
  26. voice_name="de-DE-Wavenet-C",
  27. speaking_rate=1.0,
  28. pitch=0.0,
  29. )
  30. def test_provider_name(self, provider):
  31. """Prüft den Provider-Namen."""
  32. assert provider.name == "google"
  33. def test_supported_languages(self, provider):
  34. """Prüft die unterstützten Sprachen."""
  35. languages = provider.supported_languages
  36. assert "de-DE" in languages
  37. assert "en-US" in languages
  38. assert "fr-FR" in languages
  39. assert "ja-JP" in languages
  40. def test_supports_streaming(self, provider):
  41. """Prüft, dass Streaming nicht unterstützt wird (simuliert)."""
  42. assert provider.supports_streaming is False
  43. def test_initial_state(self, provider):
  44. """Prüft den initialen Zustand."""
  45. assert provider._model_loaded is False
  46. assert provider._client is None
  47. assert len(provider._available_voices) == 0
  48. def test_speaking_rate_config(self, provider):
  49. """Prüft die Sprechrate-Konfiguration."""
  50. assert provider._speaking_rate == 1.0
  51. def test_pitch_config(self, provider):
  52. """Prüft die Tonhöhen-Konfiguration."""
  53. assert provider._pitch == 0.0
  54. @pytest.mark.asyncio
  55. async def test_synthesize_without_init_raises(self, provider):
  56. """Prüft, dass synthesize ohne Initialisierung fehlschlägt."""
  57. with pytest.raises(RuntimeError, match="Google TTS Client nicht initialisiert"):
  58. await provider.synthesize("Test")
  59. @pytest.mark.asyncio
  60. async def test_get_voices_returns_empty_before_init(self, provider):
  61. """Prüft, dass get_voices vor Initialisierung leer ist."""
  62. voices = await provider.get_voices()
  63. assert len(voices) == 0
  64. class TestGoogleTTSPlugin:
  65. """Tests für das GoogleTTSPlugin."""
  66. @pytest.fixture
  67. def plugin(self, mock_application, tmp_path):
  68. """Erstellt ein Plugin für Tests."""
  69. plugin_path = tmp_path / "tts_google"
  70. plugin_path.mkdir()
  71. config = {
  72. "name": "Google TTS",
  73. "enabled": True,
  74. "voice": "de-DE-Wavenet-C",
  75. "language": "de-DE",
  76. "speaking_rate": 1.0,
  77. "pitch": 0.0,
  78. }
  79. return GoogleTTSPlugin(mock_application, plugin_path, config)
  80. def test_plugin_initialization(self, plugin):
  81. """Prüft die Plugin-Initialisierung."""
  82. assert plugin._provider is None
  83. assert plugin.config.get("voice") == "de-DE-Wavenet-C"
  84. def test_plugin_path(self, plugin):
  85. """Prüft den Plugin-Pfad."""
  86. assert plugin.plugin_path.exists()
  87. @pytest.mark.asyncio
  88. async def test_on_unload_without_provider(self, plugin):
  89. """Prüft on_unload ohne initialisierten Provider."""
  90. await plugin.on_unload()
  91. assert plugin._provider is None
  92. class TestGoogleTTSVoiceNaming:
  93. """Tests für Google TTS Voice-Benennung."""
  94. def test_wavenet_voice_pattern(self):
  95. """Prüft das WaveNet-Voice-Benennungsschema."""
  96. voice_name = "de-DE-Wavenet-C"
  97. parts = voice_name.split("-")
  98. assert len(parts) == 4
  99. assert parts[0] == "de" # Sprache
  100. assert parts[1] == "DE" # Region
  101. assert parts[2] == "Wavenet" # Typ
  102. assert parts[3] == "C" # Variante
  103. def test_standard_voice_pattern(self):
  104. """Prüft das Standard-Voice-Benennungsschema."""
  105. voice_name = "de-DE-Standard-A"
  106. parts = voice_name.split("-")
  107. assert parts[2] == "Standard"
  108. # Integration Tests (benötigen Google Cloud Credentials)
  109. @pytest.mark.integration
  110. class TestGoogleTTSIntegration:
  111. """Integrationstests für Google TTS (benötigen Credentials)."""
  112. @pytest.fixture(autouse=True)
  113. def skip_if_not_installed(self):
  114. """Überspringt Tests wenn google-cloud-texttospeech nicht installiert ist."""
  115. pytest.importorskip("google.cloud.texttospeech", reason="google-cloud-texttospeech nicht installiert")
  116. @pytest.fixture
  117. def provider_with_credentials(self, tmp_path):
  118. """Erstellt einen Provider mit Credentials."""
  119. config = TTSConfig(language="de-DE", voice_id="de-DE-Wavenet-C")
  120. return GoogleTTSProvider(
  121. config=config,
  122. credentials_path=None, # Nutzt GOOGLE_APPLICATION_CREDENTIALS
  123. voice_name="de-DE-Wavenet-C",
  124. )
  125. @pytest.mark.asyncio
  126. @pytest.mark.slow
  127. async def test_full_synthesis_flow(self, provider_with_credentials):
  128. """Testet den vollständigen Synthese-Flow."""
  129. await provider_with_credentials.initialize()
  130. result = await provider_with_credentials.synthesize("Hallo Welt")
  131. assert result.audio_data is not None
  132. assert len(result.audio_data) > 0
  133. assert result.sample_rate == 24000
  134. assert result.duration_seconds > 0
  135. assert result.provider == "google"
  136. await provider_with_credentials.shutdown()