Evalgent
Back to Blog
Voice AI Testing

How to unit test voice interactions with Deepgram

Deepesh Jayal
10 min read
How to unit test voice interactions with Deepgram

Developers reach for unit tests to lock down behavior, but a voice interaction resists them. Live audio, streaming timing, and a language model make the same input produce slightly different output each run, and a test that is not repeatable is not a unit test. The trick is not to give up on unit testing but to test the parts that can be made deterministic, and to hand the rest to a different kind of test. This guide shows how to do that with Deepgram, and how it fits alongside the scenario testing Evalgent provides. It is a spoke of our broader Deepgram STT testing guide, focused specifically on the unit-test layer.

What a "unit" is in a voice interaction

Before you can unit test a voice agent, you have to decide what a unit is. A whole conversation is not one — it is an integration of many pieces. The units are the individual, checkable steps inside it.

Concretely, the testable units are the transcript Deepgram produces for a given audio clip, the intent or entities extracted from that transcript, the arguments of a tool call the agent decides to make, and the way a given result is formatted into a response. Each of these takes a fixed input and should produce a predictable output, which is exactly what a unit test needs. The full spoken exchange — turn-taking, latency, interruption — is not a unit and does not belong in a unit test, a distinction we return to below.

Voice interaction unit test: a repeatable, isolated test that feeds a fixed input — an audio clip or a transcript — to one piece of the agent and asserts a predictable output.

Why voice unit testing is hard

The reason voice resists unit testing is non-determinism, and it comes from three places. Live audio is never byte-identical twice. Streaming introduces timing variation in when interim and final results arrive. And a language model can phrase the same answer differently on each call. Assert an exact string against any of these and your test fails randomly, which trains the team to ignore it.

The fix is to remove the non-determinism from the inputs you control and assert at the right level of the outputs. Pin the audio by using recorded fixtures instead of live capture. Pin the model by specifying its version. And assert structure rather than exact wording where a model is involved — that a tool call fired with the right arguments, not that the agent said a particular sentence. Deterministic testing is the foundation of a trustworthy suite, a principle our testing SOP-based voice agents guide builds on.

Making Deepgram tests deterministic

Deepgram gives you two features that make voice unit tests repeatable. The first is pre-recorded transcription. Instead of streaming live audio, you send a fixed audio file to the pre-recorded API, which transcribes it and returns a result — the same file, transcribed with the same pinned model, gives you a stable transcript to assert against. That turns speech-to-text into a deterministic step you can unit test.

The second is Deepgram's mock server. As the streaming test suite docs describe, the mock server exposes an interface similar to Deepgram's streaming service but does not actually transcribe — it accepts your connection, confirms how much audio it received, and saves the audio. That lets you unit test your own client and transport code, getting the plumbing right, without depending on the network or a live transcription. Between recorded fixtures for real transcripts and the mock server for client code, you can make most of the Deepgram-facing surface deterministic.

What to unit test with Deepgram

Point your unit tests at the pieces that take a fixed input and produce a checkable output. Leave everything else to integration and scenario tests.

Unit-testableNot a unit test
Transcript of a recorded audio fixtureA full live conversation
Intent or entities from a transcriptEnd-to-end latency under load
Tool-call arguments for a given inputBarge-in and turn-taking
Response formatting from a resultBehavior across many caller types
Client and transport code (via mock)Diarization accuracy on real traffic

The left column is fast, deterministic, and cheap to run on every commit. The right column is non-deterministic by nature and needs a different tool — realistic calls, real audio, and outcome metrics. Trying to force conversation-level behavior into a unit test is the most common way voice test suites become flaky and get abandoned.

How to write a Deepgram voice unit test

A good voice unit test isolates one step and pins its inputs.

1. Record a fixture — Capture a short audio clip of a real utterance and save it as a test file.

2. Transcribe deterministically — Send the fixture to Deepgram's pre-recorded API with a pinned model version.

3. Assert the transcript — Check the transcript matches the expected text after normalizing case and punctuation, not byte-for-byte.

4. Test downstream logic on a fixed transcript — Feed a known transcript into your intent and tool logic, and assert the tool call fired with the right arguments.

5. Mock where you can — Use Deepgram's mock server to test client and transport code without a live transcription.

6. Run on every commit — Keep the suite fast so it gates each change, and re-run it when you change the model version.

For the tool-call assertions in step 4, check the exact function and arguments rather than the transcript — the same discipline our tool calling guide applies, here at the unit level.

Unit tests vs scenario tests

Unit tests and scenario tests are not competitors; they are two layers of the same pyramid. Unit tests cover the deterministic pieces, run fast, and catch regressions in transcription, intent, and tool logic on every commit. Scenario tests cover what a unit test cannot: the full conversation, over real audio, across many caller types, with outcomes measured rather than exact strings asserted.

You need both, and you need them for different reasons. A unit test tells you a specific piece still works after a code change. A scenario test tells you the whole agent still handles a real caller who interrupts, corrects themselves, and speaks with an accent. Relying on unit tests alone gives you a green suite and a broken agent, because the failures that matter most live in the conversation, not the pieces. This is where Evalgent comes in.

Common mistakes

A few habits make voice unit tests flaky or false, and they are worth naming.

Asserting exact strings against model output is the big one — a model rephrases, so assert intent and structure instead. Testing against live streaming makes the test non-deterministic by construction; use recorded fixtures. Forgetting to pin the model version means a silent upgrade can change your transcripts and break tests for reasons unrelated to your code. And testing with a single clean clip flatters your suite — include the noisy and accented fixtures that represent your real callers, so a passing unit test means something. The point of the layer is a fast, trustworthy signal, not a green checkmark that hides the calls that fail.

Beyond unit tests: testing the conversation with Evalgent

Unit tests lock down the pieces; Evalgent tests the conversation they add up to. Scenarios drive full, realistic calls — including the interruptions, corrections, noise, and accents that no unit test captures. Profiles vary caller voice, pace, and line quality across those calls, so the agent is tested against real variety rather than one clean fixture. Metrics measure outcomes — task completion, tool-call correctness, latency, transcription accuracy per condition — with thresholds you set, instead of asserting exact strings. Evaluations run the whole suite as automated batches before release, and Reviews let you replay any failing call with audio, transcript, and metrics together.

The result is the full pyramid: fast unit tests on the deterministic pieces, and scenario tests on the conversation, so a green suite actually means a working agent. For the wider Deepgram picture, see the Deepgram STT testing guide, and for the discipline overall, the AI voice agent testing pillar.

Conclusion

Unit testing voice interactions with Deepgram works when you test the deterministic pieces — transcripts from fixtures, intents, tool-call arguments — and stop trying to force a live conversation into a unit test. Pin the audio, pin the model, assert structure over exact strings, and lean on pre-recorded transcription and the mock server.

Then build the layer above: scenario tests for the conversation the pieces add up to. Unit tests keep the pieces honest; only conversation-level testing keeps the agent honest.

Frequently asked questions

How do you unit test voice interactions using Deepgram?

Test the deterministic pieces in isolation. Send a recorded audio fixture to Deepgram's pre-recorded API with a pinned model and assert the transcript, then feed a fixed transcript into your intent and tool logic and assert the tool call. Use Deepgram's mock server to test client code without a live transcription. Leave full-conversation behavior to scenario tests.

How do you write unit tests for a voice agent?

Pick the units — transcript from a fixture, intent from a transcript, tool-call arguments, response formatting — and give each a fixed input and an expected output. Pin the audio with recorded files and the model with a version, and assert structure rather than exact model wording. Keep the suite fast so it runs on every commit, and re-run it when the model changes.

How do you make voice tests deterministic?

Remove the non-determinism you control. Use recorded audio fixtures instead of live capture so the input is identical every run, pin the speech-to-text model version so upgrades do not silently change transcripts, and assert intent and structure rather than a model's exact wording. Deepgram's pre-recorded API gives stable transcripts, and its mock server lets you test client code without live transcription.

Can you mock Deepgram in tests?

Yes. Deepgram provides a mock server that exposes an interface similar to its streaming service but does not transcribe — it accepts your connection, reports how much audio it received, and saves the audio. This lets you unit test your client and transport code deterministically, without the network or a live transcription. For real transcripts, use the pre-recorded API with fixed audio fixtures instead.

What should you unit test in a voice agent?

Unit test the pieces that take a fixed input and produce a predictable output: the transcript of a recorded clip, the intent or entities from a transcript, the arguments of a tool call, and response formatting. Do not unit test the full conversation, latency under load, barge-in, or behavior across caller types — those are non-deterministic and belong in integration and scenario tests.

How do you test Deepgram transcription?

For a deterministic test, send a fixed audio fixture to Deepgram's pre-recorded API with a pinned model and assert the returned transcript matches the expected text after normalizing case and punctuation. For accuracy across real conditions — noise, accents, telephony — measure word error rate on representative audio rather than asserting exact strings, since that is an evaluation question, not a unit-test one.

What is the difference between unit tests and scenario tests for voice agents?

Unit tests check deterministic pieces — a transcript, an intent, a tool call — in isolation, run fast, and gate every commit. Scenario tests drive full, realistic conversations over real audio across many caller types and measure outcomes rather than exact strings. Unit tests tell you a piece still works after a change; scenario tests tell you the whole agent handles a real caller. You need both.

How do you test tool calls in a voice agent?

Feed a known transcript or input into your agent's logic and assert that the correct function fired with the correct arguments, checking the structured call rather than the transcript's wording. This is deterministic and belongs in your unit tests. Testing whether the tool call fires correctly across messy, real conversations — misheard values, mid-sentence corrections — is a scenario-level concern handled with synthetic callers.

Related Articles