From f70ca9751ce2d7667d68f7f5fdbf92cba27c134d Mon Sep 17 00:00:00 2001 From: James Ding Date: Tue, 18 Nov 2025 19:24:32 -0600 Subject: [PATCH 1/5] test: add integration tests for WebSocket streaming with different models --- .../test_tts_websocket_integration.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/integration/test_tts_websocket_integration.py b/tests/integration/test_tts_websocket_integration.py index 8341a18..d67e9ad 100644 --- a/tests/integration/test_tts_websocket_integration.py +++ b/tests/integration/test_tts_websocket_integration.py @@ -1,9 +1,12 @@ """Integration tests for TTS WebSocket streaming functionality.""" +from typing import get_args + import pytest from fishaudio import WebSocketOptions from fishaudio.types import Prosody, TTSConfig, TextEvent, FlushEvent +from fishaudio.types.shared import Model from .conftest import TEST_REFERENCE_ID @@ -31,6 +34,23 @@ def text_stream(): # Save the audio save_audio(audio_chunks, "test_websocket_streaming.mp3") + def test_websocket_streaming_with_different_models(self, client, save_audio): + """Test WebSocket streaming with different models.""" + models = get_args(Model) + + for model in models: + + def text_stream(): + yield f"Testing model {model} via WebSocket." + + audio_chunks = list( + client.tts.stream_websocket(text_stream(), model=model) + ) + assert len(audio_chunks) > 0, f"Failed for model: {model}" + + # Write to output directory + save_audio(audio_chunks, f"test_websocket_model_{model}.mp3") + def test_websocket_streaming_with_wav_format(self, client, save_audio): """Test WebSocket streaming with WAV format.""" config = TTSConfig(format="wav", chunk_length=200) @@ -195,6 +215,29 @@ async def text_stream(): save_audio(audio_chunks, "test_async_websocket_streaming.mp3") + @pytest.mark.asyncio + async def test_async_websocket_streaming_with_different_models( + self, async_client, save_audio + ): + """Test async WebSocket streaming with different models.""" + models = get_args(Model) + + for model in models: + + async def text_stream(): + yield f"Testing model {model} via async WebSocket." + + audio_chunks = [] + async for chunk in async_client.tts.stream_websocket( + text_stream(), model=model + ): + audio_chunks.append(chunk) + + assert len(audio_chunks) > 0, f"Failed for model: {model}" + + # Write to output directory + save_audio(audio_chunks, f"test_async_websocket_model_{model}.mp3") + @pytest.mark.asyncio async def test_async_websocket_streaming_with_format( self, async_client, save_audio From 4486356f30cb274f738d0d574beef212aad8727c Mon Sep 17 00:00:00 2001 From: James Ding Date: Tue, 18 Nov 2025 19:24:36 -0600 Subject: [PATCH 2/5] test: simplify TTS model testing by removing exception handling --- tests/integration/test_tts_integration.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/integration/test_tts_integration.py b/tests/integration/test_tts_integration.py index f6b4fc2..19e511a 100644 --- a/tests/integration/test_tts_integration.py +++ b/tests/integration/test_tts_integration.py @@ -50,15 +50,11 @@ def test_tts_with_different_models(self, client, save_audio): models = get_args(Model) for model in models: - try: - audio = client.tts.convert(text=f"Testing model {model}", model=model) - assert len(audio) > 0, f"Failed for model: {model}" - - # Write to output directory - save_audio(audio, f"test_model_{model}.mp3") - except Exception as e: - # Some models might not be available - pytest.skip(f"Model {model} not available: {e}") + audio = client.tts.convert(text=f"Testing model {model}", model=model) + assert len(audio) > 0, f"Failed for model: {model}" + + # Write to output directory + save_audio(audio, f"test_model_{model}.mp3") def test_tts_longer_text(self, client, save_audio): """Test TTS with longer text.""" From f586d17cc4417b54e3ef9d1b51f68b9d681db17c Mon Sep 17 00:00:00 2001 From: James Ding Date: Tue, 18 Nov 2025 19:25:57 -0600 Subject: [PATCH 3/5] style: format --- tests/integration/test_tts_websocket_integration.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/integration/test_tts_websocket_integration.py b/tests/integration/test_tts_websocket_integration.py index d67e9ad..04ef0fb 100644 --- a/tests/integration/test_tts_websocket_integration.py +++ b/tests/integration/test_tts_websocket_integration.py @@ -43,9 +43,7 @@ def test_websocket_streaming_with_different_models(self, client, save_audio): def text_stream(): yield f"Testing model {model} via WebSocket." - audio_chunks = list( - client.tts.stream_websocket(text_stream(), model=model) - ) + audio_chunks = list(client.tts.stream_websocket(text_stream(), model=model)) assert len(audio_chunks) > 0, f"Failed for model: {model}" # Write to output directory From 41516e3b3bb1d5a038408eda59820052f429bc43 Mon Sep 17 00:00:00 2001 From: James Ding Date: Tue, 18 Nov 2025 20:12:55 -0600 Subject: [PATCH 4/5] test: add delay to async client teardown to prevent API rate limits --- tests/integration/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 2d43b32..6426e17 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -44,9 +44,13 @@ def client(api_key): @pytest.fixture async def async_client(api_key): """Async Fish Audio client.""" + import asyncio + client = AsyncFishAudio(api_key=api_key) yield client await client.close() + # Brief delay to avoid API rate limits on WebSocket connections + await asyncio.sleep(0.3) @pytest.fixture From e037bdac34162df1b1efc618c35a71ef1135fc44 Mon Sep 17 00:00:00 2001 From: James Ding Date: Tue, 18 Nov 2025 20:22:20 -0600 Subject: [PATCH 5/5] test: add delays in WebSocket streaming tests to prevent SSL errors --- .../integration/test_tts_websocket_integration.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/integration/test_tts_websocket_integration.py b/tests/integration/test_tts_websocket_integration.py index 04ef0fb..f521a2d 100644 --- a/tests/integration/test_tts_websocket_integration.py +++ b/tests/integration/test_tts_websocket_integration.py @@ -36,6 +36,8 @@ def text_stream(): def test_websocket_streaming_with_different_models(self, client, save_audio): """Test WebSocket streaming with different models.""" + import time + models = get_args(Model) for model in models: @@ -49,6 +51,9 @@ def text_stream(): # Write to output directory save_audio(audio_chunks, f"test_websocket_model_{model}.mp3") + # Brief delay to avoid SSL errors when opening next WebSocket connection + time.sleep(0.3) + def test_websocket_streaming_with_wav_format(self, client, save_audio): """Test WebSocket streaming with WAV format.""" config = TTSConfig(format="wav", chunk_length=200) @@ -218,6 +223,8 @@ async def test_async_websocket_streaming_with_different_models( self, async_client, save_audio ): """Test async WebSocket streaming with different models.""" + import asyncio + models = get_args(Model) for model in models: @@ -236,6 +243,9 @@ async def text_stream(): # Write to output directory save_audio(audio_chunks, f"test_async_websocket_model_{model}.mp3") + # Brief delay to avoid SSL errors when opening next WebSocket connection + await asyncio.sleep(0.3) + @pytest.mark.asyncio async def test_async_websocket_streaming_with_format( self, async_client, save_audio @@ -326,6 +336,8 @@ async def test_async_websocket_streaming_multiple_calls( self, async_client, save_audio ): """Test multiple async WebSocket streaming calls in sequence.""" + import asyncio + for i in range(3): async def text_stream(): @@ -338,6 +350,9 @@ async def text_stream(): assert len(audio_chunks) > 0, f"Call {i + 1} should return audio" save_audio(audio_chunks, f"test_async_websocket_call_{i + 1}.mp3") + # Brief delay to avoid SSL errors when opening next WebSocket connection + await asyncio.sleep(0.3) + @pytest.mark.asyncio async def test_async_websocket_streaming_empty_text(self, async_client, save_audio): """Test async WebSocket streaming with empty text stream raises error."""