# Salesforce Uat Tdd

> UAT-driven development for Salesforce — write acceptance criteria first, validate with Apex tests, then build and verify

- **Type:** Skill
- **Install:** `agentstack add skill-jhillock1-salesforce-claude-skills-salesforce-uat-tdd`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [jhillock1](https://agentstack.voostack.com/s/jhillock1)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [jhillock1](https://github.com/jhillock1)
- **Source:** https://github.com/jhillock1/salesforce-claude-skills/tree/main/skills/salesforce-uat-tdd

## Install

```sh
agentstack add skill-jhillock1-salesforce-claude-skills-salesforce-uat-tdd
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# UAT-Driven Development for Salesforce

## When to Use
- Starting any new feature branch (flows, fields, flexipages, quick actions)
- Before building anything — define what "done" looks like first
- When John says "let's build X" or "we need Y"

## Core Loop

```
1. Write UAT checklist  →  Defines "done"
2. Write Apex tests     →  Validates metadata + flow behavior programmatically
3. Build in sandbox     →  Implement until tests pass
4. Manual UAT walkthrough → Walk the user's actual workflow in sandbox
5. Deploy to prod       →  Use salesforce-prod-deploy skill
6. Prod UAT walkthrough →  Walk the user's actual workflow in prod
```

**The UAT checklist is the source of truth.** Everything else serves it.

---

## Phase 1: Write the UAT Checklist

Before touching any metadata, create `docs/test_plans/-uat.xlsx` using the **xlsx skill**.

### Workbook Structure (MANDATORY — use this exact format every time)

Use the **xlsx skill** to create the workbook. The file MUST have these 7 sheets.

### Global Styling

- **Header rows:** Dark blue fill (`#003366`), white bold text, size 12
- **Section header rows:** Light blue fill (`#D6E4F0`), bold, size 11 — span full row width
- **Title cells** (Summary sheet, Test Cases title): Bold, size 14-16, dark blue text (`#003366`), no fill
- **Freeze panes:** Row 1 frozen on all data sheets (header stays visible when scrolling)
- **Column widths:** Set explicitly (don't leave at default 8.43) — description/check columns wide (50-65), ID columns narrow (8), status columns medium (10-14)

#### Sheet 1: "Summary"

| Row | Column A | Column B |
|-----|----------|----------|
| 1 | `[Feature Name]: UAT Checklist` | *(title, bold 16pt, dark blue text)* |
| 3 | `Created:` | `YYYY-MM-DD` |
| 4 | `Branch:` | `plan/feature-name` |
| 5 | `Environment:` | `Sandbox (casechek--partial)` |
| 6 | `Tester:` | `John Hillock + Claude Code` |
| 7 | `Test Class:` | `FlowTest.cls` |
| 8 | `Pass Criteria:` | `sf apex run test --class-names FlowTest` |
| 9 | `Design Doc:` | `docs/plans/...` (link to relevant design doc) |

Column A labels: bold, size 10. Column B values: regular, size 10.

#### Sheet 2: "Tier 1 - Apex Validated"

Headers (row 1): `#` | `Section` | `Check` | `Apex Test Method` | `Pass?`
Widths: 8 | 22 | 65 | 38 | 10

- Section header rows: Column A only, light blue fill (e.g., `1.1 Infrastructure — Object Name`)
- Data rows: `AV-1`, `AV-2`, etc. in Column A
- **Data validation on Pass? column:** List = `PASS,FAIL`
- Freeze panes: `A2`

#### Sheet 3: "Tier 2 - Manual UAT"

Headers (row 1): `#` | `Case #` | `Section` | `Test / Step` | `Expected Result` | `Pass?` | `Tester` | `Date` | `Notes` | `Follow-up`
Widths: 8 | 12 | 20 | 50 | 55 | 10 | 14 | 12 | 30 | 30

- Section header rows: Column A only, light blue fill (e.g., `2.1 UI & Layout`)
- Data rows: `MU-1`, `MU-2`, etc. in Column A
- Case # filled during Phase 3.5 (test case seeding)
- **Data validation on Pass? column:** List = `PASS,FAIL,BLOCKED,DEFERRED`
- Freeze panes: `A2`

#### Sheet 4: "Issues"

Headers (row 1): `#` | `Issue` | `Severity` | `Related UAT Item` | `Resolution` | `Status` | `Date Found` | `Date Resolved`
Widths: 5 | 50 | 12 | 16 | 40 | 12 | 14 | 14

- **Data validation on Severity:** List = `Critical,High,Medium,Low`
- **Data validation on Status:** List = `Open,Fixed,Deferred`
- Pre-populate 20 empty numbered rows

#### Sheet 5: "Test Cases"

Row 1: `Test Cases Created for Manual UAT` (title, bold 14pt, dark blue text)
Headers (row 3): `Case #` | `Subject` | `Status` | `Account` | `MU Items`
Widths: 12 | 55 | 20 | 30 | 16

- **Zebra striping:** Alternate rows with light gray fill (`#F2F2F2`)
- Filled during Phase 3.5

#### Sheet 6: "Re-Test"

Headers (row 1): `#` | `Case #` | `Section` | `Test / Step` | `Expected Result` | `Prior Result` | `Re-Test?` | `Fix Applied` | `Tester` | `Date` | `Notes`
Widths: 8 | 12 | 20 | 50 | 55 | 12 | 10 | 50 | 14 | 12 | 55

- Items move here from Tier 1/Tier 2 after failing and getting a fix
- Section header rows group re-test items by context (light blue fill)
- Freeze panes: `A2`

#### Sheet 7: "Known Limitations"

Headers (row 1): `#` | `Limitation` | `Reason` | `Workaround` | `Related UAT Item` | `Accepted By` | `Date`
Widths: 5 | 50 | 40 | 40 | 16 | 14 | 12

- Edge cases or behaviors that won't be fixed — documented and accepted

### Reference

The canonical example is `docs/test_plans/service-cloud-phase1-metrics-uat.xlsx`. When in doubt, match that file's structure and styling.

### Pass Criteria

**Tier 1:** `sf apex run test --class-names FlowTest` → all green. When tests pass, batch-mark every linked AV item as `PASS`.

**Tier 2:** Human walkthrough — John marks each MU item during the manual UAT session.

### Key Principle: Apex First, Manual Only When Necessary

**Every UAT item must pass the "Can Apex verify this?" gate.** If the answer is yes — even partially — it belongs in Tier 1. Tier 2 is exclusively for things that require human eyes on the UI.

**The gate question:** "Does this test check a data outcome, field value, flow behavior, or record state?" → **Tier 1 (Apex).** "Does this test check visual layout, UX coherence, element positioning, or workflow feel?" → **Tier 2 (Manual).**

Edge cases, process integrity checks, and error-handling scenarios are almost always Tier 1. They test whether flows/logic handle unusual inputs correctly — that's exactly what Apex assertions are for.

| Apex tests (Tier 1) | Manual UAT (Tier 2) |
|---------------------|---------------------|
| Fields exist and accept values | Fields are in the right page section |
| Formulas compute correctly | Formula result is visible/meaningful to user |
| Flows fire and set correct values | Flow outcomes make sense in context of workflow |
| Picklist values are valid | Picklist order/labels make sense in dropdown |
| Migration data is correct | Migrated records look right in list views |
| Flow interactions don't conflict | User doesn't see confusing intermediate states |
| **Edge cases produce correct data** | **Edge case UI doesn't confuse the user** |
| **Process integrity (rapid toggles, missing steps)** | **Slack/email notifications render correctly** |
| **Metrics calculate correctly in all scenarios** | **Dashboard/report layout makes sense** |

### UAT Checklist Rules

1. **Every item belongs to exactly one tier** — never both
2. **Tier 1 items link to their Apex test method** — so passing tests auto-pass the checklist
3. **Tier 2 items are things ONLY a human clicking through the UI can verify** — if Apex can assert the outcome, it's Tier 1
4. **Expected values are specific** — "Status = In Progress" not "Status changes"
5. **End-to-end scenarios are Tier 2 only when testing workflow coherence** — the individual assertions within them (field values, record states) should still be Tier 1
6. **When in doubt, write the Apex test** — if it passes, the item is Tier 1; if Apex literally cannot see it (page layout, tab order, toast messages), it's Tier 2

---

## Phase 2: Write Apex Tests (TDD)

Write `CaseLifecycleFlowTest.cls`-style Apex tests that validate metadata and flow behavior **before building the feature**.

### What Apex Tests Should Validate

Apex tests are your automated safety net. They catch metadata problems before you deploy.

#### 1. Fields exist and accept all picklist values

```apex
@IsTest
static void testFieldAcceptsAllValues() {
    List cases = new List();
    for (String val : new List{'Value 1', 'Value 2', 'Value 3'}) {
        cases.add(new Case(Subject = 'Test ' + val, New_Field__c = val));
    }
    insert cases;
    System.assertEquals(3, [SELECT Id FROM Case WHERE Id IN :cases].size(),
        'All picklist values should be insertable');
}
```

**Why:** Catches missing picklist values before deploy. If a value doesn't exist, the insert fails with a clear error.

#### 2. Formula fields compute correctly

```apex
@IsTest
static void testFormulaFieldComputesCorrectly() {
    Case testCase = new Case(Subject = 'Test', Status = 'In Progress');
    insert testCase;
    Case result = [SELECT My_Formula__c FROM Case WHERE Id = :testCase.Id];
    System.assertEquals(true, result.My_Formula__c,
        'Formula should return TRUE when Status = In Progress');
}
```

**Why:** Formula logic is easy to get wrong. Tests verify the formula works for every condition in the truth table.

#### 3. Record-triggered flows fire correctly

```apex
@IsTest
static void testFlowSetsFieldOnCreate() {
    Test.startTest();
    Case testCase = new Case(Subject = 'Test Flow', Status = 'New');
    insert testCase;
    Test.stopTest();

    Case result = [SELECT Auto_Field__c FROM Case WHERE Id = :testCase.Id];
    System.assertEquals('Expected Value', result.Auto_Field__c,
        'Flow should auto-set field on case creation');
}
```

**Why:** Flows are invisible. Without a test, you only discover a broken flow when a user reports it. `Test.startTest()` / `Test.stopTest()` ensures async flow execution completes.

#### 4. Flow interactions don't conflict

```apex
@IsTest
static void testEmailFlowDoesNotOverrideStatus() {
    Case testCase = new Case(Subject = 'Test', Status = 'In Progress');
    insert testCase;

    Test.startTest();
    EmailMessage em = new EmailMessage(
        ParentId = testCase.Id, Incoming = true,
        FromAddress = 'customer@example.com',
        ToAddress = 'support@casechek.com',
        Subject = 'Re: Test', TextBody = 'Reply.'
    );
    insert em;
    Test.stopTest();

    Case result = [SELECT Status FROM Case WHERE Id = :testCase.Id];
    System.assertEquals('In Progress', result.Status,
        'Inbound email should NOT change Status');
}
```

**Why:** Casechek has 149+ flows. Multiple record-triggered flows can fire on the same DML operation. Tests catch when Flow A stomps on Flow B's changes.

#### 5. Migration/data transformation outcomes

```apex
@IsTest
static void testMigrationOutcome() {
    // Validate the expected POST-migration state
    Case testCase = new Case(
        Subject = 'Migrated Case',
        Status = 'In Progress',
        Waiting_On__c = 'Customer'
    );
    insert testCase;

    Case result = [SELECT Status, Waiting_On__c, Needs_Attention__c
                    FROM Case WHERE Id = :testCase.Id];
    System.assertEquals('In Progress', result.Status);
    System.assertEquals('Customer', result.Waiting_On__c);
    System.assertEquals(false, result.Needs_Attention__c);
}
```

**Why:** One-time migration flows are high-risk. Writing tests for the expected end-state lets you verify the migration worked without manually inspecting every record.

### Apex Test Pattern

```
Test class name:  FlowTest.cls
Test setup:       @TestSetup with Account + Contact (required for Email tests)
Each method:      Tests ONE UAT checklist item
Method name:      test
Assertions:       Include failure message that maps back to UAT ID
```

### TDD Cycle

1. **Write the test first** — it will fail (field doesn't exist, flow not built yet)
2. **Build the minimum metadata** to make the test pass
3. **Run tests** — `sf apex run test --class-names FeatureFlowTest --target-org sandbox`
4. **Repeat** until all tests pass
5. **Batch-pass all Tier 1 (AV) items** — when the test suite is green, every AV item linked to a passing test gets checked off in one pass. No manual re-verification needed.

---

## Phase 3: Build in Sandbox

With UAT checklist and Apex tests defined, build the actual metadata:

1. **Fields first** — tests that insert records need fields to exist
2. **Flows second** — tests that check flow behavior need flows deployed
3. **UI components last** — flexipages, quick actions, list views

After each deployment to sandbox:
```bash
# Run tests to see what passes now
sf apex run test --class-names FeatureFlowTest --target-org casechek--partial --wait 10
```

Track progress by updating the UAT checklist — check off items as tests pass.

---

## Phase 3.5: Seed Test Cases for Manual UAT

**Before the human walkthrough, create real test records in the target org.** Every Tier 2 (MU) item must have a specific record the tester can open, not a vague instruction to "create a case."

### Why This Matters

Manual testers shouldn't waste time setting up data. They should open a record, perform the action, and verify the result. Claude creates the test cases; John validates the workflow.

### Test Case Creation Rules

1. **Every MU item gets a Case # (or record identifier)** — the tester opens that exact record
2. **Cases are pre-staged to the right state** — if MU-12 tests "customer replies," the case should already be In Progress with Waiting_On = Customer, with a real email thread
3. **Subjects are descriptive** — include the MU item number: `[MU-9] UAT: New case for state change logging`
4. **Group related MU items on the same case when sequential** — MU-9 through MU-16 (end-to-end workflow) can share one case walked through in order
5. **Use real-looking data** — real Account names from the org, realistic subjects, not "Test 123"
6. **Create via SOQL/DML (sf data create)** — not Apex test classes, so records persist in the org
7. **Record the Case # in the UAT xlsx** — in a dedicated "Case #" column on the Tier 2 sheet

### What to Create

For each MU section, seed records that let the tester start immediately:

| MU Section | Test Record State | Example |
|------------|------------------|---------|
| UI & Layout | Closed case with metrics populated | Case with state change history + metrics calculated |
| Field History | Case with recent Status/Waiting_On changes | Case changed 2-3 times so history is visible |
| E2E Workflow | Fresh case (Status = New, queue-owned) | Tester will walk it through the full lifecycle |
| Reports & Dashboard | N/A — reports query existing data | Ensure enough closed cases exist with metrics |
| Process Integrity | Edge-case states (never In Progress, rapid toggles) | One case per edge case scenario |

### Template: Test Case Insert

```bash
# Create a test case for manual UAT
sf data create record --sobject Case \
  --values "Subject='[MU-9] UAT: New case for state change logging' Status='New'" \
  --target-org sandbox --json
```

After creating all test cases, update the UAT xlsx with the Case numbers in the "Case #" column.

---

## Phase 4: Manual UAT Walkthrough (Sandbox)

**Tier 1 is already done.** All Apex tests pass, all AV items are checked off. This phase ONLY covers Tier 2 (MU items).

**Test cases are already seeded** (Phase 3.5). The tester opens the specific Case # listed in the xlsx for each MU item.

Manual UAT tests what Apex can't see — layout, UX, workflow coherence:
- Field is on the page but in the wrong section
- Quick action appears but has confusing field labels
- List view works but column order is unintuitive
- Flow fires correctly but the toast message is misleading
- Create form is missing a field that the user expects
- End-to-end workflow feels right from the agent's perspective

### Walkthrough Process

1. Open the UAT xlsx — go to the "Tier 2 - Manual UAT" sheet
2. For each MU item, open the Case # listed in the row
3. Perform the action described in "Test / Step"
4. Compare the result to "Expected Result"
5. Mark Pass/Fail in the "Pass?" column, add notes if needed
6. Log any issues on the "Issues" sheet with severity and related MU item
7. Fix issues, re-run Apex tests to ensure fixes didn't break Tier 1
8. Re-walk only the MU scenario that had the issue

**Do NOT re-verify Tier 1 items during walkthrough.** If you find yourself checking whether a field exists or a formula computes correctly, that belongs in an Apex tes

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [jhillock1](https://github.com/jhillock1)
- **Source:** [jhillock1/salesforce-claude-skills](https://github.com/jhillock1/salesforce-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jhillock1-salesforce-claude-skills-salesforce-uat-tdd
- Seller: https://agentstack.voostack.com/s/jhillock1
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
