BXUP Track progress & test yourself — free
QA & Testing · Playbook · Foundation · ~4 min read
QA & TESTING · PLAYBOOK · FOUNDATION

Ideate Edge Cases Systematically — Boundary, Pairwise, and Property-Based

The bugs that reach production live at the edges: the 256th character, February 29th, the emoji in the surname, the two flags nobody toggled together. AI amplifies three classic techniques — boundary analysis, pairwise combination, property-based testing — into an edge-case engine, while coverage judgment stays yours.

Tier: Foundation · Workflow area: Test design & planning

This playbook uses an LLM as a tireless edge-case ideation partner, then hardens the best ideas with real tooling: PICT for pairwise reduction and Hypothesis for property-based tests that find the inputs no example list contains. The model proposes; the techniques and tools verify.

When to use

  • Any input-accepting featureforms, APIs, file uploads, importers — where "what could break this?" deserves an hour, not five minutes.
  • Configuration-heavy featuresmultiple flags, roles, locales, and plans whose combinations explode beyond hand-enumeration.
  • Post-escape analysisa boundary bug shipped; you are backfilling the class of tests that would have caught it.

When NOT to use:

  • Pure logic already under property-based testsHypothesis is out-generating any brainstorm; add properties, not example lists.
  • When you can't rank the output. A 200-item edge list without risk triage becomes a backlog nobody executes; be ready to prune to the vital few.

Prerequisites

  • A written input spec for the feature — field types, limits, formats, flags; five minutes of extraction that anchors the whole exercise.
  • PICT installed (brew install pict or the Microsoft binary) for pairwise reduction.
  • Hypothesis available in the test environment (pip install hypothesis) — or fast-check/jqwik for your stack.
  • An approved assistant and, ideally, your team's past escape-bug list to seed the ideation.

The recipe

  1. Extract the input space first. For the feature, list every field with its type, limits, and format; every flag or mode; every locale/timezone assumption. This grounding stops the model brainstorming about a product it imagined.

  2. Run the structured ideation prompt — categories, not free association:

    Feature inputs: [paste field spec: name (1-100 chars, UTF-8), amount
    (0.01-99999.99, EUR/INR), date (booking, future only), role (admin/member),
    plan (free/pro)].
    
    Generate edge and negative cases in EXACTLY these categories:
    1. BOUNDARIES — at, one-below, one-above every numeric/length limit.
    2. FORMAT & ENCODING — Unicode (CJK, RTL, emoji, zero-width, combining
       diacritics), whitespace, null bytes, oversized input.
    3. TIME — leap day, DST transitions both directions, year boundary,
       epoch-adjacent, timezone-vs-UTC date disagreement.
    4. INJECTION-ADJACENT — quotes, angle brackets, template braces, path
       traversal strings (for handling, not exploitation).
    5. STATE & CONCURRENCY — double-submit, stale read, mid-flow permission
       revocation.
    For each: input value, expected safe behavior, risk (H/M/L) with one-line
    justification.
    

    Good output is specific enough to execute directly:

    BOUNDARY: amount = 99999.99 → accepted; amount = 100000.00 → rejected
    with "exceeds maximum", no partial charge created. Risk H: money.
    TIME: booking 2028-02-29 from UTC+13 on 2028-02-28 23:30 local — date
    valid at client, must not double-shift to Mar 1. Risk M.
    
  3. Compress combinations with pairwise. For the flag/role/plan/locale matrix, don't test the cross-product — generate a PICT model and let it cut the set while covering every pair:

    role:    admin, member
    plan:    free, pro, enterprise
    locale:  en-US, de-DE, ja-JP, ar-SA
    payment: card, invoice, none
    
    pict model.txt > pairwise-cases.txt && wc -l pairwise-cases.txt
    

    72 combinations become ~16 rows. Ask the model which specific pairs deserve forcing as explicit constraints (e.g., IF [plan] = "free" THEN [payment] = "none";) — then verify those constraints against the real product rules, because an invented constraint silently deletes coverage.

  4. Turn the strongest categories into properties. Example lists age; properties keep generating. Have the assistant draft Hypothesis tests for the invariants behind the categories:

    from hypothesis import given, strategies as st
    
    @given(st.text(min_size=1, max_size=100))
    def test_name_roundtrips_through_create_and_fetch(name):
        created = api.create_customer(name=name)
        assert api.get_customer(created.id).name == name
    
    @given(st.decimals(min_value="0.01", max_value="99999.99", places=2))
    def test_amount_never_loses_precision(amount):
        assert api.quote(amount).total == amount
    
    pytest test_properties.py --hypothesis-show-statistics
    

    Review generated strategies hard: models routinely write strategies that quietly exclude the interesting inputs (ASCII-only text, positive-only integers) — widen them and let shrinking find the minimal failing case.

  5. Triage into the suite. Rank by risk, promote the High items into permanent regression cases (pb-01's import path), keep properties in the unit/integration tier, and record the pruned ideas in the test plan as considered-and-rejected — that list is gold at the next escape review.

Note

For encoding categories, seed the prompt with real corpora — the big-list-of-naughty-strings repository and your own past escape bugs — the model recalls famous edge cases well but your product's specific history better.

Make it yours

  • fast-check for TypeScript/Jest shopssame property recipe with fc.assert(fc.property(...)); pair it with the Playwright suite so API-level properties and UI example tests share the boundary spec.
  • Schemathesis for API surfaceswhen an OpenAPI spec exists, let Schemathesis generate boundary/format cases from the schema automatically and spend the LLM budget on categories schemas can't express: time, state, concurrency (see pb-10).
  • jqwik/QuickTheories for JVM teamsproperties in Java/Kotlin; the ideation prompt is unchanged, only step 4's scaffolding language moves.

Quality check

  • Every numeric and length limit has its three-value boundary setat, below, above — present in the final suite, not just the brainstorm.
  • Unicode cases actually executedscreenshots or API responses prove the emoji/RTL/combining-character inputs ran; these are the cases teams list and skip.
  • Pairwise constraints verifiedeach PICT constraint traces to a documented product rule, not a model guess.
  • Properties fail when they shouldmutate the code or the property once to confirm the test can fail; a property that never fails may be vacuous.
  • Risk ranking was human-signedyou re-ranked at least some of the model's H/M/L calls; identical rankings suggest rubber-stamping.
  • Rejected ideas are recorded with a reason, so the next escape review can distinguish "didn't think of it" from "chose not to."
Pro Tip

Keep a living "edge-case museum" file of every boundary bug that ever escaped to production, and paste it into each ideation prompt — the model generalizes from your escapes into neighboring cases, which is exactly where the next one is hiding.

This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in