AgentStack
SKILL verified MIT Self-run

Salesforce Uat Tdd

skill-jhillock1-salesforce-claude-skills-salesforce-uat-tdd · by jhillock1

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

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-jhillock1-salesforce-claude-skills-salesforce-uat-tdd

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Salesforce Uat Tdd? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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
@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
@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
@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
@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
@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 testssf 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:

# 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

# 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.

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

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.