sf-testing
π―Skillfrom jaganpro/claude-code-sfskills
Executes Salesforce Apex tests with comprehensive coverage analysis, automatic failure detection, and intelligent test-fixing capabilities.
Part of
jaganpro/claude-code-sfskills(20 items)
Installation
curl -sSL https://raw.githubusercontent.com/Jaganpro/sf-skills/main/tools/install.sh | bashgit clone https://github.com/Jaganpro/sf-skillspython tools/installer.py --cli opencode --all # OpenCodepython tools/installer.py --cli codex --all # Codex (OpenAI)python tools/installer.py --cli gemini --all # Gemini (Google)+ 17 more commands
Skill Details
>
Overview
# sf-testing: Salesforce Test Execution & Coverage Analysis
Expert testing engineer specializing in Apex test execution, code coverage analysis, mock frameworks, and agentic test-fix loops. Execute tests, analyze failures, and automatically fix issues.
Core Responsibilities
- Test Execution: Run Apex tests via
sf apex run testwith coverage analysis - Coverage Analysis: Parse coverage reports, identify untested code paths
- Failure Analysis: Parse test failures, identify root causes, suggest fixes
- Agentic Test-Fix Loop: Automatically fix failing tests and re-run until passing
- Test Generation: Create test classes using sf-apex patterns
- Bulk Testing: Validate with 251+ records for governor limit safety
Workflow (5-Phase Pattern)
Phase 1: Test Discovery
Use AskUserQuestion to gather:
- Test scope (single class, all tests, specific test suite)
- Target org alias
- Coverage threshold requirement (default: 75%, recommended: 90%)
- Whether to enable agentic fix loop
Then:
- Check existing tests:
Glob: */Test.cls,Glob: /_Test.cls - Check for Test Data Factories:
Glob: */TestDataFactory*.cls - Create TodoWrite tasks
Phase 2: Test Execution
Run Single Test Class:
```bash
sf apex run test --class-names MyClassTest --code-coverage --result-format json --output-dir test-results --target-org [alias]
```
Run All Tests:
```bash
sf apex run test --test-level RunLocalTests --code-coverage --result-format json --output-dir test-results --target-org [alias]
```
Run Specific Methods:
```bash
sf apex run test --tests MyClassTest.testMethod1 --tests MyClassTest.testMethod2 --code-coverage --result-format json --target-org [alias]
```
Run Test Suite:
```bash
sf apex run test --suite-names MySuite --code-coverage --result-format json --target-org [alias]
```
Phase 3: Results Analysis
Parse test-results JSON:
```
Read: test-results/test-run-id.json
```
Coverage Summary Output:
```
π TEST EXECUTION RESULTS
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Test Run ID: 707xx0000000000
Org: my-sandbox
Duration: 45.2s
SUMMARY
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Passed: 42
β Failed: 3
βοΈ Skipped: 0
π Coverage: 78.5%
FAILED TESTS
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AccountServiceTest.testBulkInsert
Line 45: System.AssertException: Assertion Failed
Expected: 200, Actual: 199
β LeadScoringTest.testNullHandling
Line 23: System.NullPointerException: Attempt to de-reference null
β OpportunityTriggerTest.testValidation
Line 67: System.DmlException: FIELD_CUSTOM_VALIDATION_EXCEPTION
COVERAGE BY CLASS
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Class Lines Covered Uncovered %
AccountService 150 142 8 94.7% β
LeadScoringService 85 68 17 80.0% β
OpportunityTrigger 45 28 17 62.2% β οΈ
ContactHelper 30 15 15 50.0% β
UNCOVERED LINES (OpportunityTrigger)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Lines 23-28: Exception handling block
Lines 45-52: Bulk processing edge case
Lines 78-82: Null check branch
```
Phase 4: Agentic Test-Fix Loop
When tests fail, automatically:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AGENTIC TEST-FIX LOOP β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. Parse failure message and stack trace β
β 2. Identify root cause: β
β - Assertion failure β Check expected vs actual β
β - NullPointerException β Add null checks β
β - DmlException β Check validation rules, required fields β
β - LimitException β Reduce SOQL/DML in test β
β 3. Read the failing test class β
β 4. Read the class under test β
β 5. Generate fix using sf-apex skill β
β 6. Re-run the specific failing test β
β 7. Repeat until passing (max 3 attempts) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
Failure Analysis Decision Tree:
| Error Type | Root Cause | Auto-Fix Strategy |
|------------|------------|-------------------|
| System.AssertException | Wrong expected value or logic bug | Analyze assertion, check if test or code is wrong |
| System.NullPointerException | Missing null check or test data | Add null safety or fix test data setup |
| System.DmlException | Validation rule, required field, trigger | Check org config, add required fields to test data |
| System.LimitException | Governor limit hit | Refactor to use bulkified patterns |
| System.QueryException | No rows returned | Add test data or adjust query |
| System.TypeException | Type mismatch | Fix type casting or data format |
Auto-Fix Command:
```
Skill(skill="sf-apex", args="Fix failing test [TestClassName].[methodName] - Error: [error message]")
```
Phase 5: Coverage Improvement
If coverage < threshold:
- Identify Uncovered Lines:
```bash
sf apex run test --class-names MyClassTest --code-coverage --detailed-coverage --result-format json --target-org [alias]
```
- Generate Tests for Uncovered Code:
```
Read: force-app/main/default/classes/MyClass.cls (lines 45-52)
```
Then use sf-apex to generate test methods targeting those lines.
- Bulk Test Validation:
```
Skill(skill="sf-data", args="Create 251 [ObjectName] records for bulk testing")
```
- Re-run with New Tests:
```bash
sf apex run test --class-names MyClassTest --code-coverage --result-format json --target-org [alias]
```
---
Best Practices (120-Point Scoring)
| Category | Points | Key Rules |
|----------|--------|-----------|
| Test Coverage | 25 | 90%+ class coverage; all public methods tested; edge cases covered |
| Assertion Quality | 25 | Assert class used; meaningful messages; positive AND negative tests |
| Bulk Testing | 20 | Test with 251+ records; verify no SOQL/DML in loops under load |
| Test Data | 20 | Test Data Factory used; no hardcoded IDs; @TestSetup for efficiency |
| Isolation | 15 | SeeAllData=false; no org dependencies; mock external callouts |
| Documentation | 15 | Test method names describe scenario; comments for complex setup |
Scoring Thresholds:
```
βββββ 108-120 pts (90%+) β Production Ready
ββββ 96-107 pts (80-89%) β Good, minor improvements
βββ 84-95 pts (70-79%) β Acceptable, needs work
ββ 72-83 pts (60-69%) β Below standard
β <72 pts (<60%) β BLOCKED - Major issues
```
---
β TESTING GUARDRAILS (MANDATORY)
BEFORE running tests, verify:
| Check | Command | Why |
|-------|---------|-----|
| Org authenticated | sf org display --target-org [alias] | Tests need valid org connection |
| Classes deployed | sf project deploy report --target-org [alias] | Can't test undeployed code |
| Test data exists | Check @TestSetup or TestDataFactory | Tests need data to operate on |
NEVER do these:
| Anti-Pattern | Problem | Correct Pattern |
|--------------|---------|-----------------|
| @IsTest(SeeAllData=true) | Tests depend on org data, break in clean orgs | Always SeeAllData=false (default) |
| Hardcoded Record IDs | IDs differ between orgs | Query or create in test |
| No assertions | Tests pass without validating anything | Assert every expected outcome |
| Single record tests only | Misses bulk trigger issues | Always test with 200+ records |
| Test.startTest() without Test.stopTest() | Async code won't execute | Always pair start/stop |
---
CLI Command Reference
Test Execution Commands
| Command | Purpose | Example |
|---------|---------|---------|
| sf apex run test | Run tests | See examples above |
| sf apex get test | Get async test status | sf apex get test --test-run-id 707xx... |
| sf apex list log | List debug logs | sf apex list log --target-org alias |
| sf apex tail log | Stream logs real-time | sf apex tail log --target-org alias |
Useful Flags
| Flag | Purpose |
|------|---------|
| --code-coverage | Include coverage in results |
| --detailed-coverage | Line-by-line coverage (slower) |
| --result-format json | Machine-parseable output |
| --output-dir | Save results to directory |
| --synchronous | Wait for completion (default) |
| --test-level RunLocalTests | All tests except managed packages |
| --test-level RunAllTestsInOrg | Every test including packages |
---
Test Patterns & Templates
Pattern 1: Basic Test Class
Use template: templates/basic-test.cls
```apex
@IsTest
private class AccountServiceTest {
@TestSetup
static void setupTestData() {
// Use Test Data Factory for consistent data creation
List
insert accounts;
}
@IsTest
static void testCreateAccount_Success() {
// Given
Account testAccount = new Account(Name = 'Test Account');
// When
Test.startTest();
Id accountId = AccountService.createAccount(testAccount);
Test.stopTest();
// Then
Assert.isNotNull(accountId, 'Account ID should not be null');
Account inserted = [SELECT Name FROM Account WHERE Id = :accountId];
Assert.areEqual('Test Account', inserted.Name, 'Account name should match');
}
@IsTest
static void testCreateAccount_NullInput_ThrowsException() {
// Given
Account nullAccount = null;
// When/Then
try {
Test.startTest();
AccountService.createAccount(nullAccount);
Test.stopTest();
Assert.fail('Expected IllegalArgumentException was not thrown');
} catch (IllegalArgumentException e) {
Assert.isTrue(e.getMessage().contains('cannot be null'),
'Error message should mention null: ' + e.getMessage());
}
}
}
```
Pattern 2: Bulk Test (251+ Records)
Use template: templates/bulk-test.cls
```apex
@IsTest
static void testBulkInsert_251Records() {
// Given - 251 records crosses the 200-record batch boundary
List
// When
Test.startTest();
insert accounts; // Triggers fire in batches of 200, then 51
Test.stopTest();
// Then
Integer count = [SELECT COUNT() FROM Account];
Assert.areEqual(251, count, 'All 251 accounts should be inserted');
// Verify no governor limits hit
Assert.isTrue(Limits.getQueries() < 100,
'Should not approach SOQL limit: ' + Limits.getQueries());
}
```
Pattern 3: Mock Callout Test
Use template: templates/mock-callout-test.cls
```apex
@IsTest
private class ExternalAPIServiceTest {
// Mock class for HTTP callouts
private class MockHttpResponse implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
HttpResponse res = new HttpResponse();
res.setStatusCode(200);
res.setBody('{"success": true, "data": {"id": "12345"}}');
return res;
}
}
@IsTest
static void testCallExternalAPI_Success() {
// Given
Test.setMock(HttpCalloutMock.class, new MockHttpResponse());
// When
Test.startTest();
String result = ExternalAPIService.callAPI('test-endpoint');
Test.stopTest();
// Then
Assert.isTrue(result.contains('success'), 'Response should indicate success');
}
}
```
Pattern 4: Test Data Factory
Use template: templates/test-data-factory.cls
```apex
@IsTest
public class TestDataFactory {
public static List
List
for (Integer i = 0; i < count; i++) {
accounts.add(new Account(
Name = 'Test Account ' + i,
Industry = 'Technology',
BillingCity = 'San Francisco'
));
}
return accounts;
}
public static List
List
for (Integer i = 0; i < count; i++) {
contacts.add(new Contact(
FirstName = 'Test',
LastName = 'Contact ' + i,
AccountId = accountId,
Email = 'test' + i + '@example.com'
));
}
return contacts;
}
// Convenience method with insert
public static List
List
insert accounts;
return accounts;
}
}
```
---
Agentic Test-Fix Loop Implementation
How It Works
When the agentic loop is enabled, sf-testing will:
- Run tests and capture results
- Parse failures to identify error type and location
- Read source files (test class + class under test)
- Analyze root cause using the decision tree above
- Generate fix by invoking sf-apex skill
- Re-run failing test to verify fix
- Iterate until passing or max attempts (3)
Example Agentic Flow
```
User: "Run tests for AccountService with auto-fix enabled"
Claude:
- sf apex run test --class-names AccountServiceTest --code-coverage --result-format json
- Parse results: 1 failure - testBulkInsert line 45 NullPointerException
- Read AccountServiceTest.cls (line 45 context)
- Read AccountService.cls (trace the null reference)
- Identify: Missing null check in AccountService.processAccounts()
- Skill(sf-apex): Add null safety to AccountService.processAccounts()
- Deploy fix
- Re-run: sf apex run test --tests AccountServiceTest.testBulkInsert
- β Passing! Report success.
```
---
Cross-Skill Integration
| Skill | When to Use | Example |
|-------|-------------|---------|
| sf-apex | Generate test classes, fix failing code | Skill(skill="sf-apex", args="Create test class for LeadService") |
| sf-data | Create bulk test data (251+ records) | Skill(skill="sf-data", args="Create 251 Leads for bulk testing") |
| sf-deploy | Deploy test classes to org | Skill(skill="sf-deploy", args="Deploy tests to sandbox") |
| sf-debug | Analyze failures with debug logs | Skill(skill="sf-debug", args="Analyze test failure logs") |
---
Common Test Failures & Fixes
| Failure | Likely Cause | Fix |
|---------|--------------|-----|
| MIXED_DML_OPERATION | User + non-setup object in same transaction | Use System.runAs() or separate transactions |
| CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY | Trigger or flow error | Check trigger logic with debug logs |
| REQUIRED_FIELD_MISSING | Test data incomplete | Add required fields to TestDataFactory |
| DUPLICATE_VALUE | Unique field conflict | Use dynamic values or delete existing |
| FIELD_CUSTOM_VALIDATION_EXCEPTION | Validation rule fired | Meet validation criteria in test data |
| UNABLE_TO_LOCK_ROW | Record lock conflict | Use FOR UPDATE or retry logic |
---
Dependencies
Required: Target org with sf CLI authenticated
Recommended: sf-apex (for auto-fix), sf-data (for bulk test data), sf-debug (for log analysis)
Install: /plugin install github:Jaganpro/sf-skills/sf-testing
---
Documentation
| Document | Description |
|----------|-------------|
| [testing-best-practices.md](docs/testing-best-practices.md) | General testing guidelines |
| [cli-commands.md](docs/cli-commands.md) | SF CLI test commands |
| [mocking-patterns.md](docs/mocking-patterns.md) | Mocking vs Stubbing, DML mocking, HttpCalloutMock |
| [performance-optimization.md](docs/performance-optimization.md) | Fast tests, reduce execution time |
Templates
| Template | Description |
|----------|-------------|
| [basic-test.cls](templates/basic-test.cls) | Standard test class with Given-When-Then |
| [bulk-test.cls](templates/bulk-test.cls) | 251+ record bulk testing |
| [mock-callout-test.cls](templates/mock-callout-test.cls) | HTTP callout mocking |
| [test-data-factory.cls](templates/test-data-factory.cls) | Reusable test data creation |
| [dml-mock.cls](templates/dml-mock.cls) | DML abstraction for 35x faster tests |
| [stub-provider-example.cls](templates/stub-provider-example.cls) | StubProvider for dynamic behavior |
---
Credits
See [CREDITS.md](CREDITS.md) for acknowledgments of community resources that shaped this skill.
---
License
MIT License. See [LICENSE](LICENSE) file.
Copyright (c) 2024-2025 Jag Valaiyapathy
More from this repository10
Generates production-ready Lightning Web Components for Salesforce using PICKLES architecture, ensuring robust, accessible, and performant UI development with comprehensive testing and integration.
Validates and tests AI agent interactions and workflows within Salesforce using automated testing frameworks and scenarios.
Generates and validates Salesforce flows with comprehensive 110-point scoring, ensuring Winter '26 best practices and high-performance flow design.
Deploys Salesforce metadata and code changes to specified orgs using flexible configuration and streamlined deployment workflows.
Generates Salesforce ERD diagrams, LWC mockups, and architecture visuals using Gemini and Nano Banana Pro AI technology.
Executes Salesforce data operations with expert SOQL querying, bulk data management, and test data generation across Salesforce orgs.
Generates legacy Agentforce agents using Agent Script syntax with 100-point scoring for maintaining existing agent patterns.
Analyzes YouTube video details, extracts metadata, and provides insights about video content, views, and engagement metrics.
Analyzes Salesforce Permission Sets, revealing access hierarchies, detecting specific permissions, and auditing user access across objects, fields, and Apex classes.
Generates and configures Salesforce Connected Apps and External Client Apps with comprehensive OAuth setup, security validation, and 120-point scoring mechanism.