Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
forcedotcom avatar

Generating Apex Test

  • 1.6k installs
  • 763 repo stars
  • Updated July 24, 2026
  • forcedotcom/afv-library

This is a copy of generating-apex-test by forcedotcom - installs and ranking accrue to the original listing.

generating-apex-test is a Claude Code skill that generates complete, Salesforce-compliant Apex test classes with bulk, positive, negative, and exception patterns for developers who must meet org coverage rules without wr

About

generating-apex-test is a Claude Code skill from forcedotcom/afv-library that scaffolds Apex test classes matching Salesforce deployment requirements. Generated tests include @TestSetup with TestDataFactory data, bulk operations using 251 or more records, positive and negative method paths, and exception-handling cases with Test.startTest and Test.stopTest boundaries. The template follows Given-When-Then structure and names methods like shouldPerformExpectedBehavior_WhenValidInput. Salesforce developers reach for generating-apex-test when adding coverage for new Apex classes, satisfying bulkification rules, or replacing hand-written test boilerplate before CI validation or org promotion.

  • Generates @isTest classes with proper @TestSetup using TestDataFactory
  • Includes positive, negative, and bulk (251+ records) test methods
  • Enforces Given-When-Then structure with explicit Assert statements
  • Provides exception handling and edge-case test templates
  • Outputs ready-to-run test class following Salesforce best practices

Generating Apex Test by the numbers

  • 1,593 all-time installs (skills.sh)
  • +2 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/forcedotcom/afv-library --skill generating-apex-test

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1.6k
repo stars763
Security audit3 / 3 scanners passed
Last updatedJuly 24, 2026
Repositoryforcedotcom/afv-library

How do you write Salesforce Apex bulk test classes?

Generate complete, Salesforce-compliant Apex test classes that follow bulk, positive, negative, and exception patterns without manual boilerplate.

Who is it for?

Salesforce developers who need deployment-ready Apex test classes that satisfy bulkification and governor-limit best practices.

Skip if: Non-Salesforce Java or Node backends, or teams that only need manual exploratory testing without automated Apex coverage.

When should I use this skill?

The user asks to generate Apex tests, bulk test coverage, or Salesforce-compliant test classes for a specific Apex class.

What you get

Complete @isTest Apex classes with TestSetup, 251-record bulk cases, positive/negative tests, and exception coverage.

  • Complete Apex test class source
  • Bulk and exception test method scaffolds

By the numbers

  • Scaffolds bulk Apex tests with 251 or more records per test class

Files

SKILL.mdMarkdownGitHub ↗

Generating Apex Tests

Generate production-ready Apex test classes and run disciplined test-fix loops with coverage analysis.

Core Principles

1. One behavior per method — each test method validates a single scenario. Separate positive, negative, and bulk tests. NEVER combine related-but-distinct inputs (e.g., null and empty) in one method — create _NullInput_ and _EmptyInput_ as separate test methods 2. Bulkify tests — test with 251+ records to cross the 200-record trigger batch boundary. Batch Apex exception: in test context only one execute() invocation runs, so set batchSize >= testRecordCount. See references/async-testing.md 3. Isolate test data — every @TestSetup must delegate record creation to a TestDataFactory class. If none exists, create one first. Never build record lists inline in @TestSetup. Never rely on org data (SeeAllData=false) or hardcoded IDs. For duplicate rule handling, see references/test-data-factory.md 4. Assert meaningfully — use exact expected values computed from test data setup. NEVER use range assertions or approximate counts when the value is deterministic. Always include failure messages. See references/assertion-patterns.md 5. Use `Assert` class onlyAssert.areEqual, Assert.isTrue, Assert.fail, etc. Never use legacy System.assert, System.assertEquals, or System.assertNotEquals 6. Mock external boundaries — use HttpCalloutMock for callouts, Test.setFixedSearchResults for SOSL, DML mock classes for database isolation. Design for testability via constructor injection. See references/mocking-patterns.md 7. Test negative paths — validate error handling and exception scenarios, not just happy paths 8. Wrap with start/stop — pair Test.startTest() with Test.stopTest() to reset governor limits and force async execution

Test.startTest() / Test.stopTest()

Always wrap the code under test in Test.startTest() / Test.stopTest():

  • Resets governor limits so the test measures only the code under test
  • Executes async operations synchronously (queueables, batch, future methods)
  • Fires scheduled jobs immediately

Test Code Anti-Patterns

Anti-PatternFix
SOQL/DML inside loopsQuery once before the loop; use Map<Id, SObject> for lookups
Magic numbers in assertionsDerive expected values from setup constants
God test class (>500 lines)Split into multiple test classes by behavior area
Long test methods (>30 lines)Extract Given/When/Then into helper methods
Generic Exception catchCatch the specific expected type (e.g., DmlException)

Workflow

Step 1 — Gather Context

Before generating or fixing tests, identify:

  • the target production class(es) under test
  • existing test classes, test data factories, and setup helpers
  • desired test scope (single class, specific methods, suite, or local tests)
  • coverage threshold (75% minimum for deploy, 90%+ recommended)
  • org alias when running tests against an org

Step 2 — Generate the Test Class

Apply the structure, naming conventions, and patterns from the asset templates and reference docs.

MANDATORY — File Deliverables: For every test class, create BOTH files: 1. {ClassName}Test.cls — the test class (use assets/test-class-template.cls as starting point) 2. {ClassName}Test.cls-meta.xml — the metadata file:

<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>66.0</apiVersion>
    <status>Active</status>
</ApexClass>

If no TestDataFactory exists in the project, create TestDataFactory.cls + TestDataFactory.cls-meta.xml using assets/test-data-factory-template.cls.

@TestSetup Example
@TestSetup
static void setupTestData() {
    List<Account> accounts = TestDataFactory.createAccounts(251, true);
}
Test Method Structure

Use Given/When/Then:

@isTest
static void shouldUpdateStatus_WhenValidInput() {
    // Given
    List<Account> accounts = [SELECT Id FROM Account];

    // When
    Test.startTest();
    MyService.processAccounts(accounts);
    Test.stopTest();

    // Then
    List<Account> updated = [SELECT Id, Status__c FROM Account];
    Assert.areEqual(251, updated.size(), 'All accounts should be processed');
}
Negative Test — Exception Pattern

Use try/catch with Assert.fail to verify expected exceptions:

@isTest
static void shouldThrowException_WhenInvalidInput() {
    // Given
    List<Account> emptyList = new List<Account>();

    // When/Then
    Test.startTest();
    try {
        MyService.processAccounts(emptyList);
        Assert.fail('Expected MyCustomException to be thrown');
    } catch (MyCustomException e) {
        Assert.isTrue(e.getMessage().contains('cannot be empty'),
            'Exception message should indicate empty input');
    }
    Test.stopTest();
}
Naming Convention
  • should[ExpectedResult]_When[Scenario]: shouldSendNotification_WhenOpportunityClosedWon
  • [SubjectOrAction]_[Scenario]_[ExpectedResult]: AccountUpdate_ChangeName_Success

Step 3 — Run Tests

Start narrow when debugging; widen after the fix is stable.

# Single test class
sf apex run test --class-names MyServiceTest --result-format human --code-coverage --target-org <alias>

# Specific test methods
sf apex run test --tests MyServiceTest.shouldUpdateStatus_WhenValidInput --result-format human --target-org <alias>

# All local tests
sf apex run test --test-level RunLocalTests --result-format human --code-coverage --target-org <alias>

Step 4 — Analyze Results

Focus on:

  • failing methods — exception types and stack traces
  • uncovered lines and weak coverage areas
  • whether failures indicate bad test data, brittle assertions, or broken production logic

Step 5 — Fix Loop

When tests fail, run a disciplined fix loop (max 3 iterations — stop and surface root cause if still failing):

1. Read the failing test class and the class under test 2. Identify root cause from error messages and stack traces 3. Apply fix — adjust test data or assertions for test-side issues; delegate production code issues to the generating-apex skill 4. Rerun the focused test before broader regression 5. Repeat until all tests pass, iteration limit reached, or root cause requires design change

Step 6 — Validate Coverage

LevelCoveragePurpose
Production deploy75% minimumRequired by Salesforce
Recommended90%+Best practice target
Critical paths100%Business-critical code

Cover all paths: positive, negative/exception, bulk (251+ records), callout/async.

What to Test by Component

ComponentKey Test Scenarios
TriggerBulk insert/update/delete, recursion guard, field change detection
ServiceValid/invalid inputs, bulk operations, exception handling
ControllerPage load, action methods, view state
Batchstart/execute/finish, scope matching (batch size >= record count), Database.Stateful tracking, error handling, chaining (separate methods — finish() calling Database.executeBatch() throws UnexpectedException)
QueueableChaining (only first job runs in tests), bulkification, error handling, callout mocks before Test.startTest()
CalloutSuccess response, error response, timeout
SelectorValid/null/empty inputs, bulk (251+), field population, sort order, WITH USER_MODE via System.runAs
ScheduledDirect execution via execute(null), CRON registration via CronTrigger query
Platform EventTest.enableChangeDataCapture(), Test.getEventBus().deliver(), verify subscriber side effects

Output Expectations

Deliverables per test class:

  • {ClassName}Test.cls + {ClassName}Test.cls-meta.xml (match API version of class under test; default 66.0)
  • TestDataFactory.cls + TestDataFactory.cls-meta.xml (if not already present)

Reference Files

Load on demand for detailed patterns:

ReferenceWhen to use
references/test-data-factory.mdTestDataFactory patterns, field overrides, duplicate rule handling
references/assertion-patterns.mdAssertion best practices, anti-patterns, common pitfalls
references/mocking-patterns.mdHttpCalloutMock, DML mocking, StubProvider, SOSL, Email, Platform Events
references/async-testing.mdBatch, Queueable, Future, Scheduled job testing

Related skills

How it compares

Pick generating-apex-test over generic unit-test skills when output must follow Salesforce @isTest, bulk, and governor-limit conventions.

FAQ

What bulk record count does generating-apex-test use?

generating-apex-test scaffolds bulk tests with 251 or more records in @TestSetup via TestDataFactory, matching Salesforce bulkification guidance for governor-limit-safe Apex test classes.

Which test patterns does generating-apex-test include?

generating-apex-test generates positive tests, negative tests, and exception-handling cases inside @isTest classes, using Test.startTest and Test.stopTest and Given-When-Then method structure.

Is Generating Apex Test safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Testing & QAbackendtesting

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.