diff --git a/src/pipecat/tests/utils.py b/src/pipecat/tests/utils.py index 356fb8545..ca18c4c4d 100644 --- a/src/pipecat/tests/utils.py +++ b/src/pipecat/tests/utils.py @@ -199,13 +199,13 @@ async def run_test( # # Down frames # - received_down_frames: Sequence[Frame] = [] - if expected_down_frames is not None: - while not received_down.empty(): - frame = await received_down.get() - if not isinstance(frame, EndFrame) or not send_end_frame: - received_down_frames.append(frame) + received_down_frames: list[Frame] = [] + while not received_down.empty(): + frame = await received_down.get() + if not isinstance(frame, EndFrame) or not send_end_frame: + received_down_frames.append(frame) + if expected_down_frames is not None: down_frames_printed = "[" for frame in received_down_frames: down_frames_printed += f"{frame.__class__.__name__}, " @@ -225,12 +225,12 @@ async def run_test( # # Up frames # - received_up_frames: Sequence[Frame] = [] - if expected_up_frames is not None: - while not received_up.empty(): - frame = await received_up.get() - received_up_frames.append(frame) + received_up_frames: list[Frame] = [] + while not received_up.empty(): + frame = await received_up.get() + received_up_frames.append(frame) + if expected_up_frames is not None: print("received UP frames =", received_up_frames) print("expected UP frames =", expected_up_frames) diff --git a/tests/test_piper_tts.py b/tests/test_piper_tts.py index 662b9a40c..2b1dae577 100644 --- a/tests/test_piper_tts.py +++ b/tests/test_piper_tts.py @@ -77,28 +77,36 @@ async def test_run_piper_tts_success(aiohttp_client): TTSSpeakFrame(text="Hello world."), ] - expected_returned_frames = [ - AggregatedTextFrame, - TTSStartedFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSAudioRawFrame, - TTSStoppedFrame, - TTSTextFrame, - ] - frames_received = await run_test( tts_service, frames_to_send=frames_to_send, - expected_down_frames=expected_returned_frames, ) down_frames = frames_received[0] + frame_types = [type(f) for f in down_frames] + + # Verify key frames are present + assert AggregatedTextFrame in frame_types + assert TTSStartedFrame in frame_types + assert TTSStoppedFrame in frame_types + assert TTSTextFrame in frame_types + + # Verify ordering: Started → audio → Stopped → Text + started_idx = frame_types.index(TTSStartedFrame) + stopped_idx = frame_types.index(TTSStoppedFrame) + text_idx = frame_types.index(TTSTextFrame) + assert started_idx < text_idx < stopped_idx, ( + "Expected: TTSStartedFrame < TTSTextFrame < TTSStoppedFrame" + ) + + # Frames between Started and Stopped must all be audio or text + for i in range(started_idx + 1, stopped_idx): + assert frame_types[i] in (TTSAudioRawFrame, TTSTextFrame), ( + f"Unexpected frame type between Started and Stopped: {frame_types[i]}" + ) + + # All audio frames have correct sample rate audio_frames = [f for f in down_frames if isinstance(f, TTSAudioRawFrame)] + assert len(audio_frames) >= 1, "Expected at least one audio frame" for a_frame in audio_frames: assert a_frame.sample_rate == 24000, "Sample rate should match the default (24000)" @@ -128,7 +136,7 @@ async def test_run_piper_tts_error(aiohttp_client): TTSSpeakFrame(text="Error case.", append_to_context=False), ] - expected_down_frames = [AggregatedTextFrame, TTSStoppedFrame, TTSTextFrame] + expected_down_frames = [AggregatedTextFrame, TTSStartedFrame, TTSTextFrame, TTSStoppedFrame] expected_up_frames = [ErrorFrame]