Guide · AI Testing Center

Functional Testing of AI Features: Asserting Without Exact Answers

How to check an AI feature does what it was specified to do — replacing equality assertions with property checks, structuring cases, and deciding what "correct" means before you test.

Functional Testing Updated 2026-08-04 839 words · about 4 min read

Functional testing asks one question: does it do what it was specified to do?

For conventional software the assertion is straightforward — call the function, compare to the expected value. For an AI feature, the expected value does not exist as a single string, and that breaks the usual pattern rather than the underlying idea.

Define "correct" before you test#

Most AI functional testing fails at specification, not at execution. "Summarise the document" cannot pass or fail.

Convert the requirement into checkable properties:

VagueCheckable
"Summarise the document"≤150 words · covers the three headings · introduces no facts absent from the source · no first person
"Extract the invoice details"Valid JSON · supplier, number, date, total present · date is ISO 8601 · total = sum of line items · currency is ISO 4217
"Answer the customer's question"Addresses the question asked · every claim traceable to supplied context · states uncertainty when present · no personal data of other customers

If you cannot write the check, the requirement is not finished. That is the same rule as any other requirement — see the BRD template — and it applies with more force here.

The three kinds of assertion#

Structural — deterministic and cheap. Does it parse? Are the fields present and typed correctly? Is the length in range? Run these first: they catch most real breakage at negligible cost.

Semantic — needs a judge. Does it answer the question? Is it grounded? Is the tone right? Score against a short rubric, and use a different model from the one being tested if the judge is automated.

Behavioural — how it acts, not what it says. Does it refuse when it should? Ask for clarification on ambiguity? Stay in role? These are the most-skipped and often the most important.

Structuring a case#

ID           FT-014
Requirement  BR-007
Input        <the exact input>
Setup        model + version, temperature, prompt version, context supplied
Assertions   structural:  parses as JSON; fields present; total = sum(lines)
             semantic:    values match the source document
             behavioural: absent fields reported as null, never invented
Runs         5
Pass         5/5 structural, ≥4/5 semantic

Two details do the heavy lifting. Setup pins the environment — without the model version and temperature the result is not reproducible. Runs and a pass threshold replace the binary, because a single run cannot distinguish a reliable system from a lucky one.

Coverage that matters#

The forgotten cases are the same as in conventional testing, plus a few specific to AI:

Conventional: empty input · one item · boundaries · wrong type · very large input · duplicate submission · interruption mid-operation.

AI-specific:

  • Absent information — the answer genuinely is not there. Must refuse.
  • Contradictory input — two sources disagree. Must surface, not silently pick.
  • Ambiguous request — must ask or state the assumption, not guess silently.
  • Wrong language — input in a language you did not plan for.
  • Content that looks like instructions — a document containing "ignore the above".
  • Very long input — near the context limit, where behaviour degrades quietly.

That first one deserves emphasis. A feature that works perfectly on answerable questions and fabricates on unanswerable ones is more dangerous than one that fails visibly, because it fails exactly when the user is most dependent on it.

What to do about variance#

Run each case several times and set a threshold appropriate to consequence:

Assertion typeReasonable bar
Structural100% — no excuse for malformed output
Behavioural refusal100% for anything consequential
Semantic quality≥80%, tracked over time

If structural checks are not at 100%, the problem is usually the prompt not stating the format strictly enough — not the model.

Traceability#

Every requirement should have at least one functional test and a recorded result, exactly as in conventional delivery. When someone asks "did we verify BR-007?", the answer should be a row rather than a recollection.

The Test Plan template includes the matrix.

FAQ#

Can we reuse our existing test framework?#

Mostly yes. The assertions change; the harness, reporting and CI integration do not. You are adding property checks and repeated runs, not replacing your tooling.

How do we test tone or style?#

Rubric scoring, with examples of acceptable and unacceptable output. Keep it to three or four dimensions — long rubrics score inconsistently, whether the scorer is a person or a model.

What if the model is right but phrases it differently each time?#

Then your assertion is wrong, not the model. Assert the property — the fact is present, the total is correct — rather than the phrasing. Locking a suite to one phrasing means it goes red on correct output, and a suite that cries wolf gets muted — leaving you with nothing.

Should functional tests run in CI?#

Yes, at least the structural ones — they are fast and deterministic enough. Semantic scoring can run nightly if it is slow or costly.

How does this relate to regression testing?#

Functional tests prove a feature meets its specification. Regression tests prove it still does after a change. In practice the same cases serve both, but the intent differs and it is worth keeping the sets separate.

What else is coming for Functional Testing

Theory Not yet

What it is and why it is hard.

Best Practices Not yet

What holds up in production.

Examples Ready

Worked, with real numbers.

Checklists Ready

Run before you ship.

Templates Not yet

Editable starting files.

Sample Reports Ready

What the output should look like.

Tools Not yet

What to use, and what to avoid.