Typorithm · medium

9. Schema checks and semantic contracts

qatestingtest-designindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

9. Schema checks and semantic contracts

0%

Concept and contract

Distinguish valid JSON, structural shape and useful business values.

JSON parsing establishes syntax, not a business contract. A payload can be valid JSON while missing an id, using text for a count or containing an unsupported country. Separate structural checks from semantic rules so a failure explains which promise was broken.

A schema can require fields and constrain values, but the chosen schema still needs review. Decide whether unknown properties are ignored or rejected and whether a missing optional field differs from an explicit null. These are API design choices, not automatic benefits of JSON.

Mechanism and worked example

The example documents a role with nonempty string id and title plus a finite country vocabulary.

The example documents a role with nonempty string id and title plus a finite country vocabulary. It also names the unknown-field policy. The local decoder projects the checked fields, so an unrelated extra field is not exposed through the trusted result.

Check representative valid and invalid payloads independently. A schema test should reject the wrong primitive, but a business test may also need to reject an empty id that is technically a string. Presence, type and meaning are different observations.

Complete worked example

json

{
  "required": {
    "id": "nonempty string",
    "title": "nonempty string",
    "country": [
      "US",
      "UA"
    ]
  },
  "extraFields": "ignore and project"
}
Reasoning
The contract names required fields, semantic limits and its extra-field policy.

Counterexamples and common mistakes

The weak check accepts any object because JSON parsing succeeded.

The weak check accepts any object because JSON parsing succeeded. It would admit an empty object and a role whose country is a number. A UI may display placeholders instead of crashing, making this contract failure easy to miss visually.

Do not regenerate expected schema rules from the exact response under test. That turns a provider regression into a new expectation automatically. Review intentional contract changes with both producers and consumers.

Counterexample: what this check misses

json

{
  "raw": {},
  "check": "JSON.parse succeeded",
  "accepted": true
}
Reasoning
Valid JSON can still violate every useful role requirement.

Independent practice: small task

Create payload cases for a valid role, an empty id, a missing title and an unsupported country.

Create payload cases for a valid role, an empty id, a missing title and an unsupported country. Add one extra-field case under the documented ignore-and-project policy. Begin with the valid baseline and change one field at a time.

State expected acceptance rather than just listing malformed objects. Optional extension: model an optional website that may be absent but cannot be numeric. Keep the basic four required-field cases small and explainable.

Step 1: Write one valid payload. Step 2: Change one required field per invalid case.

Practice starter: solve before reading the solution

json

{
  "cases": [
    {
      "raw": {
        "id": "r1",
        "title": "QA",
        "country": "UA"
      },
      "accepted": "TODO"
    },
    {
      "raw": {
        "id": "",
        "title": "QA",
        "country": "UA"
      },
      "accepted": "TODO"
    }
  ]
}
Reasoning
Change one field from a known valid baseline for each negative case.
  • Hint 1: Parsing does not validate a schema.
  • Hint 2: State the extra-field policy explicitly.

Solution, tests and trade-offs

The solution varies one contract dimension per case.

The solution varies one contract dimension per case. The extra-field case remains accepted because projection drops unneeded fields. A strict additional-properties policy would produce a different correct answer, so the policy belongs beside the fixtures.

The verifier runs each case through the local decoder and checks that projected valid results contain only allowed fields. It also rejects a weakened shape-only decoder with an empty-id case. These checks do not establish that every future schema revision is compatible.

Practice solution and acceptance checks

json

{
  "cases": [
    {
      "raw": {
        "id": "r1",
        "title": "QA",
        "country": "UA"
      },
      "accepted": true
    },
    {
      "raw": {
        "id": "",
        "title": "QA",
        "country": "UA"
      },
      "accepted": false
    },
    {
      "raw": {
        "id": "r1",
        "country": "UA"
      },
      "accepted": false
    },
    {
      "raw": {
        "id": "r1",
        "title": "QA",
        "country": "XX"
      },
      "accepted": false
    },
    {
      "raw": {
        "id": "r1",
        "title": "QA",
        "country": "UA",
        "private": "omit"
      },
      "accepted": true
    }
  ]
}
Reasoning
Acceptance and projection are both tested against the declared policy.

Interview reasoning and next step

In interviews, distinguish syntax, structure and semantics using three concrete payloads.

In interviews, distinguish syntax, structure and semantics using three concrete payloads. Explain missing versus null and the chosen extra-field policy. Avoid saying that a TypeScript interface validates an HTTP response.

Next, apply the same precision to authorization: a response with a perfect schema can still belong to the wrong account.

Optional stretch — after the core task works: Add absent, null and numeric optional website cases.

Computer practice: download the companion lab at https://applydjinn.com/typorithm/qa-lab-20261105.zip. Read its README, install the pinned tools and run the accepted examples before attempting a starter. The mobile reader preserves your reading and self-check progress; the local lab runs browser tests separately.

Distinguish valid JSON, structural shape and useful business values.