All posts
TestingTest CasesQuality AssuranceDocumentationAutomation

Test case documentation with Mermaid diagrams

8 min readThe MermaidCreator team

Manual test cases live in spreadsheets; automated test suites hide in code. But neither format helps a QA engineer see the forest: What are all the paths through this feature? Which scenarios are covered? Where are the gaps? A diagram showing happy paths, error cases, and edge cases gives teams a testability roadmap and guards against test duplication and overlooked scenarios.

Why diagram test cases?

Spreadsheets are linear — "Test 1, Test 2, Test 3" with no sense of how they relate or whether they're redundant.
Test code is detailed — it shows how to test, not what scenarios exist.
Diagrams are holistic — they show the entire test surface at once: happy path, validation errors, edge cases, boundary conditions.

A test diagram becomes your acceptance criteria—"we're done testing when we cover every branch in this diagram."

Basic test case diagram: login flow

flowchart TD
    A([User visits login])
    B["Enter email"]
    C["Enter password"]
    D{Email<br/>registered?}
    E{Password<br/>correct?}
    F{2FA<br/>enabled?}
    G["Send 2FA code"]
    H["Verify code"]
    I{Code<br/>valid?}
    J["Create session"]
    K([Logged in])
    
    L["Show error:<br/>Email not found"]
    M["Show error:<br/>Wrong password"]
    N["Show error:<br/>2FA code invalid"]
    
    A --> B --> C --> D
    D -->|No| L --> B
    D -->|Yes| E
    E -->|No| M --> C
    E -->|Yes| F
    F -->|No| K
    F -->|Yes| G --> H --> I
    I -->|No| N --> H
    I -->|Yes| J --> K
    
    style K fill:#d4f1d4
    style L fill:#f1d4d4
    style M fill:#f1d4d4
    style N fill:#f1d4d4

Test cases from this diagram:

IDScenarioHappy/Error
TC1Email not registeredError
TC2Wrong passwordError
TC3Login without 2FAHappy path
TC42FA code validHappy path
TC52FA code invalidError
TC6Invalid 2FA code, retry succeedsError recovery

Each diamond and path becomes a test. Color-coding (green = pass, red = error) helps testers see coverage at a glance.

Boundary and edge case testing

Test diagrams make it easy to spot what not to forget:

flowchart TD
    A([User enters password])
    B{Length<br/>≥ 8?}
    C{Has<br/>uppercase?}
    D{Has<br/>number?}
    E{Has<br/>special<br/>char?}
    F["Accept"]
    
    G["Show error:<br/>Too short"]
    H["Show error:<br/>Missing upper"]
    I["Show error:<br/>Missing number"]
    J["Show error:<br/>Missing special"]
    
    A --> B
    B -->|No| G --> A
    B -->|Yes| C
    C -->|No| H --> A
    C -->|Yes| D
    D -->|No| I --> A
    D -->|Yes| E
    E -->|No| J --> A
    E -->|Yes| F
    
    style F fill:#d4f1d4
    style G fill:#f1d4d4
    style H fill:#f1d4d4
    style I fill:#f1d4d4
    style J fill:#f1d4d4

Test cases:

  • "password" (8 chars, no upper) → error
  • "Password" (8 chars, has upper, no number) → error
  • "Password1" (has upper, number, no special) → error
  • "Password1!" (all checks pass) → accept

Without a diagram, a tester might miss the "missing number" case. With it, all paths are visible.

Testing with conditionals: feature flags and user roles

Real-world features often have conditionals: "if feature flag X is on" or "if user is admin." Diagrams model all combinations:

flowchart TD
    A{Feature<br/>flag<br/>on?}
    B{User<br/>role}
    
    C["Show<br/>new UI"]
    D{Admin?}
    E["Can edit"]
    F["Cannot edit"]
    
    G["Show<br/>old UI"]
    H["Can only<br/>view"]
    
    A -->|Yes| C
    C --> B
    B -->|Admin| D
    D -->|Yes| E
    B -->|Regular| F
    
    A -->|No| G
    G --> H
    
    style E fill:#d4f1d4
    style F fill:#d4f1d4
    style H fill:#d4f1d4

This reveals all combinations:

FlagRoleExpectedTest Case
OnAdminEdit button shown, functionalTC1
OnRegularEdit button hiddenTC2
OffAdminOld UI, no edit buttonTC3
OffRegularOld UI, no view detailsTC4

Without the diagram, a tester might skip TC3 and TC4 and miss a regression.

API test scenarios: request/response flow

Sequence diagrams work great for API testing—they show request, validation, processing, and response:

sequenceDiagram
    participant Client
    participant API
    participant DB
    
    Client->>+API: POST /order { cart_id, payment_token }
    
    alt Valid token
        API->>API: Validate cart
        
        alt Cart in session
            API->>+DB: Check stock
            DB-->>-API: { in_stock: true }
            
            API->>+DB: Create order
            DB-->>-API: { order_id: 123 }
            
            API-->>Client: 201 { order_id, status: pending }
        else Cart expired
            API-->>Client: 400 { error: "Cart expired" }
        end
    else Invalid token
        API-->>Client: 401 { error: "Unauthorized" }
    end

Test scenarios from this diagram:

IDScenarioExpected
TC1Valid token, in-stock cart201 with order ID
TC2Valid token, expired cart400 error
TC3Invalid/missing token401 error
TC4Out-of-stock item (extend diagram)400 error

Testers use this to build test scripts:

  • Mock a token and a valid cart → expect 201
  • Mock an expired cart session → expect 400
  • Omit the token → expect 401

Test coverage matrix: all paths covered?

For critical flows, create a matrix to track test coverage:

flowchart TD
    A([Payment])
    B{Amount<br/>valid?}
    C{Card<br/>on file?}
    D["Charge card"]
    E{Payment<br/>approved?}
    F["Confirm order"]
    
    G["Show error:<br/>Invalid amount"]
    H["Request<br/>new card"]
    I["Show error:<br/>Declined"]
    
    A --> B
    B -->|No| G
    B -->|Yes| C
    C -->|No| H
    C -->|Yes| D
    D --> E
    E -->|No| I
    E -->|Yes| F
    
    style F fill:#d4f1d4

Coverage checklist:

  • TC1: Invalid amount → error (path B→G)
  • TC2: No card on file → request new (path C→H)
  • TC3: Payment declined → error (path E→I)
  • TC4: Valid payment → confirm (happy path)

Once all boxes are checked, you have complete path coverage.

Boundary value testing

Diagrams help you spot where to test boundaries:

flowchart TD
    A([User age input])
    B{Age<br/>> 17?}
    C{Age<br/>< 150?}
    D["Accept"])
    
    E["Reject:<br/>Too young"]
    F["Reject:<br/>Invalid input"]
    
    A --> B
    B -->|No| E
    B -->|Yes| C
    C -->|No| F
    C -->|Yes| D
    
    style D fill:#d4f1d4

Boundary test cases:

  • Age 17 → reject (at boundary, should fail)
  • Age 18 → accept (just above boundary)
  • Age 149 → accept (just below upper boundary)
  • Age 150 → reject (at upper boundary)
  • Age 0 → reject (negative invalid)
  • Age -1 → reject (negative invalid)
  • Age 999 → reject (far above upper boundary)

Diagrams make the boundary points obvious so testers remember to test them.

Regression testing: what to re-test after a change?

After a code change, a diagram shows what must be tested:

Before: We fixed a bug in the "password reset" flow.
Question: What do we need to regression-test?
Answer: All paths connected to password reset in the diagram.

flowchart TD
    A([User login])
    B{Remember<br/>password?}
    C["Use password"]
    D["Click forgot<br/>password"]
    E["Send reset<br/>email"]
    F["User clicks<br/>link in email"]
    G["Enter new<br/>password"]
    H["Confirm<br/>reset"]
    I["Login with<br/>new password"]
    J([Success])
    
    K["Link expired<br/>after 1 hour"]
    L["Request<br/>new link"]
    
    A --> B
    B -->|Yes| C --> J
    B -->|No| D --> E --> F
    F --> G
    F -->|After 1h| K --> L
    L --> E
    G --> H --> I --> J
    
    style J fill:#d4f1d4

After fixing password reset, regression tests:

  • TC1: Login with old password before reset
  • TC2: Forgot password → receive email
  • TC3: Click reset link → reset form
  • TC4: Submit new password → confirm
  • TC5: Login with new password
  • TC6: Reset link expires after 1 hour → request new link

Without the diagram, a tester might only test the happy path (TC5) and miss the edge cases.

Test prioritization: high-risk paths

Not all test cases are equal. Some paths are high-risk (financial, security) and need more testing:

flowchart TD
    A([Start])
    B{Authentication<br/>passed?}
    C{Payment<br/>processing?}
    D{Data<br/>sensitive?}
    
    E["Low risk"]
    F["HIGH RISK:<br/>Test in staging"]
    G["CRITICAL:<br/>Security review"]
    
    A --> B
    B -->|No| E
    B -->|Yes| C
    C -->|No| E
    C -->|Yes| D
    D -->|No| F
    D -->|Yes| G
    
    style G fill:#ffcccc
    style F fill:#ffe6cc
    style E fill:#e6f2ff

Prioritize testing (high to low risk):

  1. CRITICAL — authentication, PII handling, payment
  2. HIGH — business logic, data persistence
  3. NORMAL — UI, reporting, non-critical flows

Best practices for test case diagrams

  1. Keep diagrams focused — one feature per diagram (not the entire application)
  2. Use consistent shapes — diamonds for conditions, rectangles for actions
  3. Color-code by type — green = happy path, red = error, yellow = warning
  4. Label clearly — "email not found" beats "error"
  5. Track coverage — check off each test case once it's written
  6. Update with the feature — when requirements change, redraw the diagram
  7. Link to test scripts — each node should map to one or more actual tests

FAQ

Should I diagram every feature or just critical ones?
Start with critical flows: authentication, payment, data access. Then expand to features that have been buggy or are new. Over time, you'll have diagrams for your whole app.

Can I use diagrams instead of a test management tool?
Diagrams show what to test; test management tools track when tests run and who did them. Use both: diagrams for design, tools for tracking.

How detailed should test diagrams be?
Detailed enough that someone unfamiliar with the feature can write test cases from it. Too much detail (every SQL query, every API call) makes it unreadable; too little (just "login") makes it useless.

What if the feature changes?
Update the diagram and the test cases together. The diagram is your contract—when it changes, you know what new tests to write and what old tests might no longer apply.

Should developers help write test diagrams?
Yes. Developers know edge cases and error paths that product specs miss. A diagram co-created by PMs, QA, and developers catches more bugs.

Build your first test diagram in MermaidCreator and share it with your team to ensure comprehensive test coverage.

Related posts