Test systems with no reliable oracle using metamorphic relations — equivalence-preserving input transforms whose outputs must agree, with concrete relations for LLM/NLP stability.
Installs into .claude/skills of the current project.
Are you the author of Coding?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/andreibesleaga-coding-ab484e55)
---
name: metamorphic-testing
description: Test systems with no reliable oracle using metamorphic relations — equivalence-preserving input transforms whose outputs must agree, with concrete relations for LLM/NLP stability.
triggers: [test without a correct answer oracle, write metamorphic relations, check paraphrase invariance, test llm output stability, build a metamorphic relation suite, bypass the oracle problem]
tags: [coding, testing, metamorphic, llm, nlp]
core: false
context_cost: medium
---
# Metamorphic Testing
## Goal
Test systems where you cannot say what the *single correct output* is — the oracle problem.
You often can't assert "the model's answer to this question is X", but you *can* assert that
two related inputs must produce related outputs. A *metamorphic relation* (MR) is exactly that:
a transformation of the input paired with the expected relationship between the outputs. If you
reword a question without changing its meaning, a robust system should give an equivalent
answer; if it doesn't, you found a bug without ever knowing the "right" answer. This skill
produces a **metamorphic relation suite** — a set of MRs, especially for LLM/NLP stability,
where exact-match oracles are impossible. Like property-based testing, MT samples and raises
confidence; it does not prove.
## Steps
1. **Identify the oracle gap.** Confirm there is no cheap, reliable way to know the exact
correct output (typical for ML/LLM/NLP, scientific computation, rendering, search ranking).
If a real oracle exists, use a direct assertion or `pbt-strategy.skill` instead — MT is for
when it does not.
2. **Derive metamorphic relations.** Each MR = an input transform + the required output
relationship. Core families:
- **Paraphrase / semantic-equivalence invariance**: reword the input preserving meaning →
output should be equivalent (same classification, semantically-equivalent answer). The
workhorse MR for LLM robustness.
- **Noise / filler invariance**: add whitespace, harmless boilerplate, irrelevant trailing
text, casing changes → output should be unchanged.
- **Negation / symmetry**: negate the premise → output should flip in the defined way (a
sentiment classifier on a negated sentence; "is A before B" vs "is B before A").
- **Order-permutation invariance**: reorder items that should be order-independent (a set of
facts, a list to summarize, retrieval candidates) → output should be equivalent.
- **Monotonicity/scaling**: strengthen a signal (add more supporting evidence) → confidence
or ranking should not move the wrong direction.
3. **Define the output-equivalence check per MR.** "Equivalent" is rarely exact-string for
LLM/NLP. Choose the comparison: exact match (for classifiers/structured output), set or
order-insensitive equality, or *semantic* similarity (embedding cosine above a threshold,
or an LLM-as-judge equivalence call). State the tolerance explicitly — a too-loose check
passes everything; too-tight flags benign variation.
4. **Distinguish hand-designed MRs from live-LLM checks.** Prefer **hand-designed MRs** with
deterministic transforms and a fixed equivalence check — they are reproducible and cheap.
Using a *live LLM* to generate paraphrases or to judge equivalence introduces its own
nondeterminism and failure modes (the judge can be wrong, the paraphraser can drift meaning),
so treat live-LLM MRs as noisier signal: pin generated paraphrases as fixtures once found,
and cross-check judge verdicts. Never let an unvalidated LLM silently define "equivalent."
5. **Run, sample, and triage.** Apply each MR across a diverse seed set of inputs (sample — you
cannot cover all). On a violation, the *pair* (original + transformed inputs and their
diverging outputs) is the bug report. Triage genuine instability vs an over-tight equivalence
check. Pin confirmed violations as regression fixtures.
6. **Compose MRs for coverage.** Different MRs catch different bugs: paraphrase invariance finds
brittleness to wording; order-permutation finds positional bias; negation finds shallow
pattern-matching. A single MR is narrow; assemble a suite that spans the failure modes you
care about.
## Constraints
- MT **samples** inputs and **raises confidence**; it does **not prove** correctness. A passing
MR suite means "no violation found in the sampled pairs under these relations" — nothing more.
- **Different MRs catch different bugs.** No single relation is sufficient; the suite's value is
in breadth. Report which failure modes are and are not covered.
- An MR can only assert a *relationship*, never absolute correctness. A system can satisfy every
MR and still be uniformly wrong (stable but incorrect). Say so; MT checks consistency, not truth.
- Equivalence checks for NLP are themselves fuzzy. A semantic-similarity or LLM-judge check has
its own error rate; tune and disclose the threshold, and treat borderline diffs as inconclusive.
- Live-LLM paraphrasers/judges add nondeterminism; results from them are noisier and must be
pinned/cross-checked, not trusted blind.
## Output Format
Produce a **metamorphic relation suite** containing:
- Each MR: the input transform, the required output relationship, and the equivalence check
(exact / set / semantic-threshold / judge) with its tolerance.
- For each MR, whether it is hand-designed (deterministic) or live-LLM-assisted (with the
noise caveat noted).
- The seed input set and sampling scope.
- The list of failure modes the suite covers and those it does not.
- An explicit honesty note: MT samples and raises confidence, checks consistency not truth, and
does not prove correctness. Cross-reference `pbt-strategy.skill` for invariant-style properties
where an oracle does exist.
## Security & Guardrails
### 1. Skill Security
- **Risk**: A passing MR suite is reported as "the model is correct/safe," when MT only shows
consistency. Mitigation: every report MUST state MT checks relationships not truth and does not
prove; the agent MUST NOT escalate "MRs passed" into "output is correct" — a uniformly wrong
system passes invariance MRs.
- **Risk**: An over-loose equivalence threshold makes every MR pass vacuously, hiding real
instability. Mitigation: the agent MUST record the chosen tolerance and justify it, and flag
thresholds so loose that meaningfully different outputs would still be judged equivalent.
### 2. System Integration Security
- **Risk**: Running MRs (especially paraphrase generation + judging) against a live/paid model
multiplies calls and cost, or hits rate limits. Mitigation: bound the seed set and pin generated
paraphrases as fixtures; cap total model calls and prefer cached/deterministic transforms in CI.
- **Risk**: Metamorphic inputs that transform untrusted user text could carry injected content
into the system under test or the judge. Mitigation: treat all transformed inputs as untrusted
data, isolate them from any instruction context, and never let a transformed input alter test
control flow.
### 3. LLM & Agent Guardrails
- **Risk**: A live-LLM paraphraser silently changes the input's *meaning*, so a "violation" is
really a bad transform, not a real bug (false positive) — or a meaning-preserving paraphrase is
judged equivalent when the output genuinely regressed (false negative). Mitigation: validate that
transforms preserve semantics (human spot-check or a second judge), and label live-LLM MR results
as lower-confidence requiring confirmation.
- **Risk**: The agent fabricates MRs that do not actually preserve meaning (e.g. a "paraphrase"
that adds new constraints), producing spurious failures. Mitigation: each MR's transform MUST be
justified as meaning-preserving (or meaning-flipping, for negation MRs) with an example pair, and
the agent MUST mark agent-generated relations as proposed pending review.