A single test scenario with preconditions, steps, and expected outcomes.
A test case is a single verifiable check: given these preconditions, perform these steps, and the result must be exactly this. It is the smallest unit at which "does the software do what we said" becomes a yes-or-no question. Its discipline lies in the word expected. A check with no predetermined expected result cannot fail, and a test that cannot fail proves nothing.
Glenford Myers fixed the philosophy in *The Art of Software Testing* (1979). His provocation was that testing is the process of executing a program with the intent of finding errors, which makes a successful test one that fails. From that follows his rule for a good test case: it must include the expected output, defined before the program runs, so the tester is forced to judge the result against a standard rather than rationalise whatever the program happens to produce.
The structure was later codified. IEEE 829, the Standard for Software Test Documentation, defines a test case by its parts: a set of input values, execution preconditions, expected results, and postconditions, written for a stated objectiveObjectiveStrategyA strategic goal (OKR)View reference → such as exercising a particular path or verifying a specific requirement. That last clause matters. It ties each test case back to a requirement, which is how a team answers "have we tested everything we promised?"
Practice then split along two lines. The agile movement pushed expected behaviour earlier, into executable acceptance tests and behaviour-driven specifications, so the check and the requirement are written together. Test automation moved the bulk of routine cases into code that runs on every commit, leaving humans for the exploratory work machines handle poorly. The unit stayed the same throughout: one case, one expected result, one verdict.
A team builds a password reset flow. One acceptance criterionAcceptance CriterionProduct SpecificationA condition that must be met for a story to be doneView reference → reads: "a reset link expires 30 minutes after it is issued." That single criterion spawns several test cases. One has the precondition of a link issued 29 minutes ago, the step of clicking it, and the expected result that the reset form loads. Another sets the link at 31 minutes old and expects a clear "link expired" message with an option to request a new one. A third feeds a link that was already used once and expects rejection. Each case is independently runnable and gives a clean pass or fail. The first is automated as part of the regression suite; the awkward edge of a clock that crosses the boundary mid-request gets a manual case, because the timing is fiddly to reproduce in code. Together they pin the criterion down from every angle a real user might hit.
In the Unified Product Graph, Test CaseQuality AssuranceAn individual test case lives in the testing region as the atom of verification. It rolls up through test_caseTest SuitecontainsTest Casehierarchy and emits an outcome through test_suite_contains_test_caseTest CaseproducesTest Resultcausal, which keeps the durable check separate from its run-by-run history. Its traceability edges are what make the structure earn its place: test_case_produces_test_resultTest CasevalidatesAcceptance Criterioncross-domain ties the check to the promise it enforces, and test_case_validates_acceptance_criteriontest_case_covers_story_statement reaches further up to the story it came from. Walk those edges backward and you can answer the question every release manager dreads, "which requirements have no tests behind them," by querying for criteria with no incoming validation.
Type-specific fields on BaseNode
execution_typestringHow the test is executed
prioritystringTest importance
preconditionsstring[]Conditions required before running the test
stepsstring[]Ordered steps to execute the test
expected_resultstringWhat a passing result looks like
last_resultstringResult of the most recent execution
sectionstringHierarchical grouping within the parent suite (e.g. "Checkout / Payment")
templatestringTest case template applied (e.g. "BDD", "Given-When-Then", "exploratory charter")
referencesstring[]Links to requirements, tickets, or external documentation
automation_statusstringAutomation status. Closed set so coverage dashboards can group test cases by automation maturity. Pair with `automation_tool` for the specific framework (e.g. Playwright, Cypress) when automated.
automation_toolstringAutomation tool or framework (e.g. `'Playwright'`, `'Cypress'`, `'Jest'`). Free-text; the universe of tools is open. Pairs with `automation_status` per audit recommendation (#40).
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
3 phases — initial: draft
4 edge types connected to this entity.
test_suite_contains_test_casetest_case_produces_test_resulttest_case_validates_acceptance_criteriontest_case_covers_user_story