A function either returns the right value or it does not. An LLM can answer the same question three different ways, all of them arguably correct, and a fourth way that sounds equally confident and is completely wrong. Traditional testing has no real answer for that fourth case, since it was built around the assumption that correctness is binary. Evaluation is the discipline built specifically for the case where it is not, and DeepEval is the most widely used open source tool for actually doing it.
assert response == expected_output assumes determinism. Ask a language model the same question twice and you can get two differently worded answers that are both fine, which breaks that assertion immediately even when nothing is actually wrong. The harder problem sits underneath that surface issue, a response can be fluent, confident, and completely fabricated, and a simple string comparison has no way to catch that. You need something that can judge quality and factual grounding, not just match text. DeepEval's introduction to LLM evaluation frames this same gap as the reason evaluation exists as a distinct practice from conventional unit testing.
That is what evaluation frameworks solve. Instead of comparing an output to one fixed correct answer, you score it against criteria, does it answer the question, does it stay consistent with the source material it was given, does it invent anything the source material does not support.
DeepEval's own documentation draws a specific distinction worth understanding before writing any code. A Golden is a template, the input and, optionally, an expected output or context, essentially what you want to test. A Test Case is that same template fully populated with what your LLM application actually produced when you ran it, the real output alongside any retrieval context or tool calls involved. A Metric is the scoring logic that judges whether the resulting Test Case meets your bar.

Keeping this separation matters because it is what lets the same set of Goldens get reused across different prompts, different models, or different releases of your application, comparing results over time instead of writing one off assertions each time.
Reference based metrics compare an output against something concrete you already have, expected text, retrieved source documents, a known correct answer. DeepEval's Answer Relevancy and Faithfulness metrics work this way, checking a response against the question asked or the context it was given.
The other approach, G-Eval, uses an LLM as the judge itself, reasoning through custom criteria you describe in plain language rather than matching against a fixed reference at all.
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCaseParams
tone_metric = GEval(
name="Support Tone",
criteria="Check whether the response is empathetic and avoids sounding dismissive of user frustration.",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
)
This is the right tool when nothing in DeepEval's fifty plus built in metrics matches what actually matters for your product, an unusual tone requirement, a domain specific correctness rule, anything you can describe but not easily compute directly.
A single test case proves the mechanism works. Real evaluation needs volume, dozens or hundreds of examples run consistently, which is what an EvaluationDataset is built for.
import pytest
from deepeval import assert_test
from deepeval.dataset import EvaluationDataset, Golden
from deepeval.test_case import LLMTestCase
from deepeval.metrics import AnswerRelevancyMetric
dataset = EvaluationDataset(goldens=[
Golden(input="What is your return policy?"),
Golden(input="Do you ship internationally?"),
Golden(input="How do I cancel a subscription?"),
])
for golden in dataset.goldens:
dataset.add_test_case(LLMTestCase(
input=golden.input,
actual_output=your_app(golden.input),
))
@pytest.mark.parametrize("test_case", dataset.test_cases)
def test_support_bot(test_case):
assert_test(test_case, [AnswerRelevancyMetric()])
Run it with deepeval test run test_file.py and every golden in the dataset gets evaluated in one pass, the same way a normal pytest suite runs many test functions in one command. This is what turns evaluation from a one off spot check into something that can gate a release the way any other automated test suite does. RCV Academy's AI Augmented QA roadmap places this exact skill alongside automation and API testing as one of the core competencies for testers moving into AI heavy teams.
Do I need labeled correct answers for every input to evaluate anything? No. Metrics like G-Eval and Answer Relevancy do not require a fixed expected output, since they judge quality against criteria or context rather than matching a reference answer word for word.
Is DeepEval only useful once I already have a large dataset of test inputs? No. DeepEval includes a Synthesizer that can generate Goldens automatically from your own documents or existing knowledge base, which is a reasonable way to build a starting dataset rather than writing every input by hand.
How is this different from just asking an LLM to grade another LLM's answer manually? The mechanism is similar, an LLM judging output, but DeepEval standardizes it into repeatable metrics with defined scoring logic, integrates it into pytest and CI pipelines, and lets you compare results consistently across model or prompt changes rather than a one off manual check.
RCV Academy's ISTQB Generative AI certification course covers the conceptual foundation behind everything in this post, while the Generative AI and AI Agents for QA course puts DeepEval to work inside a full testing workflow.
Categories: : API Testing, Automation