@salesforce/afv-skills 1.5.1 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +16 -415
  2. package/package.json +5 -3
  3. package/skills/building-ui-bundle-app/SKILL.md +325 -0
  4. package/skills/building-ui-bundle-frontend/SKILL.md +122 -0
  5. package/skills/{building-webapp-react-components → building-ui-bundle-frontend}/implementation/component.md +1 -1
  6. package/skills/creating-b2b-commerce-store/SKILL.md +169 -0
  7. package/skills/creating-b2b-commerce-store/references/store-vs-storefront.md +169 -0
  8. package/skills/deploying-ui-bundle/SKILL.md +77 -0
  9. package/skills/generating-apex/CREDITS.md +30 -0
  10. package/skills/generating-apex/SKILL.md +335 -189
  11. package/skills/generating-apex/assets/abstract.cls +12 -8
  12. package/skills/generating-apex/assets/batch.cls +7 -7
  13. package/skills/generating-apex/assets/domain.cls +5 -5
  14. package/skills/generating-apex/assets/dto.cls +11 -11
  15. package/skills/generating-apex/assets/exception.cls +1 -1
  16. package/skills/generating-apex/assets/interface.cls +2 -2
  17. package/skills/generating-apex/assets/invocable.cls +115 -0
  18. package/skills/generating-apex/assets/queueable.cls +6 -6
  19. package/skills/generating-apex/assets/rest-resource.cls +300 -0
  20. package/skills/generating-apex/assets/schedulable.cls +7 -7
  21. package/skills/generating-apex/assets/selector.cls +7 -7
  22. package/skills/generating-apex/assets/service.cls +4 -4
  23. package/skills/generating-apex/assets/trigger.cls +45 -0
  24. package/skills/generating-apex/assets/utility.cls +5 -5
  25. package/skills/generating-apex/references/AccountDeduplicationBatch.cls +7 -7
  26. package/skills/generating-apex/references/AccountSelector.cls +10 -10
  27. package/skills/generating-apex/references/AccountService.cls +9 -9
  28. package/skills/generating-apex-test/CREDITS.md +30 -0
  29. package/skills/generating-apex-test/SKILL.md +165 -74
  30. package/skills/generating-apex-test/assets/test-class-template.cls +23 -54
  31. package/skills/generating-apex-test/assets/test-data-factory-template.cls +0 -1
  32. package/skills/generating-apex-test/references/assertion-patterns.md +38 -95
  33. package/skills/generating-apex-test/references/async-testing.md +59 -142
  34. package/skills/generating-apex-test/references/mocking-patterns.md +77 -76
  35. package/skills/generating-apex-test/references/test-data-factory.md +29 -130
  36. package/skills/generating-experience-react-site/SKILL.md +9 -9
  37. package/skills/generating-experience-react-site/docs/configure-metadata-digital-experience.md +1 -1
  38. package/skills/generating-flexipage/SKILL.md +28 -12
  39. package/skills/generating-ui-bundle-features/SKILL.md +45 -0
  40. package/skills/generating-ui-bundle-metadata/SKILL.md +106 -0
  41. package/skills/{managing-webapp-agentforce-conversation-client → implementing-ui-bundle-agentforce-conversation-client}/SKILL.md +5 -5
  42. package/skills/{managing-webapp-agentforce-conversation-client → implementing-ui-bundle-agentforce-conversation-client}/references/constraints.md +2 -2
  43. package/skills/{managing-webapp-agentforce-conversation-client → implementing-ui-bundle-agentforce-conversation-client}/references/examples.md +1 -1
  44. package/skills/{implementing-webapp-file-upload → implementing-ui-bundle-file-upload}/SKILL.md +11 -11
  45. package/skills/searching-media/SKILL.md +1 -1
  46. package/skills/{using-webapp-salesforce-data → using-ui-bundle-salesforce-data}/SKILL.md +52 -25
  47. package/skills/using-ui-bundle-salesforce-data/references/mutation-query-generation.md +140 -0
  48. package/skills/using-ui-bundle-salesforce-data/references/query-testing.md +78 -0
  49. package/skills/using-ui-bundle-salesforce-data/references/read-query-generation.md +307 -0
  50. package/skills/using-ui-bundle-salesforce-data/references/schema-introspection.md +53 -0
  51. package/skills/using-ui-bundle-salesforce-data/references/ui-bundle-integration.md +221 -0
  52. package/skills/{using-webapp-salesforce-data → using-ui-bundle-salesforce-data/scripts}/graphql-search.sh +75 -23
  53. package/skills/building-webapp-data-visualization/SKILL.md +0 -72
  54. package/skills/building-webapp-data-visualization/implementation/bar-line-chart.md +0 -316
  55. package/skills/building-webapp-data-visualization/implementation/dashboard-layout.md +0 -189
  56. package/skills/building-webapp-data-visualization/implementation/donut-chart.md +0 -181
  57. package/skills/building-webapp-data-visualization/implementation/stat-card.md +0 -150
  58. package/skills/building-webapp-react-components/SKILL.md +0 -96
  59. package/skills/configuring-webapp-csp-trusted-sites/SKILL.md +0 -90
  60. package/skills/configuring-webapp-metadata/SKILL.md +0 -158
  61. package/skills/creating-webapp/SKILL.md +0 -138
  62. package/skills/deploying-webapp-to-salesforce/SKILL.md +0 -226
  63. package/skills/installing-webapp-features/SKILL.md +0 -210
  64. /package/skills/{building-webapp-react-components → building-ui-bundle-frontend}/implementation/header-footer.md +0 -0
  65. /package/skills/{building-webapp-react-components → building-ui-bundle-frontend}/implementation/page.md +0 -0
  66. /package/skills/{configuring-webapp-csp-trusted-sites/implementation/metadata-format.md → generating-ui-bundle-metadata/implementation/csp-metadata-format.md} +0 -0
  67. /package/skills/{managing-webapp-agentforce-conversation-client → implementing-ui-bundle-agentforce-conversation-client}/references/style-tokens.md +0 -0
  68. /package/skills/{managing-webapp-agentforce-conversation-client → implementing-ui-bundle-agentforce-conversation-client}/references/troubleshooting.md +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @description Service class for Account business logic.
2
+ * Service class for Account business logic.
3
3
  * Provides account deduplication, enrichment, and territory assignment.
4
4
  * Delegates queries to AccountSelector and SObject manipulation to AccountDomain.
5
5
  * @author Generated by Apex Class Writer Skill
@@ -14,7 +14,7 @@ public with sharing class AccountService {
14
14
  // ─── Public API ──────────────────────────────────────────────────────
15
15
 
16
16
  /**
17
- * @description Merges duplicate Account records into a master record.
17
+ * Merges duplicate Account records into a master record.
18
18
  * The master record retains its field values; child records are reparented.
19
19
  * @param masterIds Map of master Account Id to Set of duplicate Account Ids to merge
20
20
  * @return List of master Account Ids that were successfully merged
@@ -77,7 +77,7 @@ public with sharing class AccountService {
77
77
  }
78
78
 
79
79
  /**
80
- * @description Assigns accounts to territories based on Billing State/Country.
80
+ * Assigns accounts to territories based on Billing State/Country.
81
81
  * Uses Custom Metadata Type (Territory_Mapping__mdt) for mappings.
82
82
  * @param accountIds Set of Account Ids to assign territories for
83
83
  * @return Number of accounts successfully updated
@@ -115,7 +115,7 @@ public with sharing class AccountService {
115
115
  // ─── Convenience Overloads ───────────────────────────────────────────
116
116
 
117
117
  /**
118
- * @description Single-account territory assignment convenience method
118
+ * Single-account territory assignment convenience method
119
119
  * @param accountId The Account Id to assign a territory for
120
120
  * @return 1 if updated, 0 if no change needed
121
121
  */
@@ -126,7 +126,7 @@ public with sharing class AccountService {
126
126
  // ─── Private Helpers ─────────────────────────────────────────────────
127
127
 
128
128
  /**
129
- * @description Loads territory mappings from Custom Metadata
129
+ * Loads territory mappings from Custom Metadata
130
130
  * @return Map of territory key (State:Country) to territory name
131
131
  */
132
132
  private static Map<String, String> loadTerritoryMappings() {
@@ -139,7 +139,7 @@ public with sharing class AccountService {
139
139
  }
140
140
 
141
141
  /**
142
- * @description Builds a consistent territory lookup key
142
+ * Builds a consistent territory lookup key
143
143
  * @param state The billing state
144
144
  * @param country The billing country
145
145
  * @return A normalized key string
@@ -149,7 +149,7 @@ public with sharing class AccountService {
149
149
  }
150
150
 
151
151
  /**
152
- * @description Chunks a list of Accounts into sublists of the given size
152
+ * Chunks a list of Accounts into sublists of the given size
153
153
  * @param accounts The accounts to chunk
154
154
  * @param chunkSize Maximum chunk size
155
155
  * @return List of account sublists
@@ -172,7 +172,7 @@ public with sharing class AccountService {
172
172
  }
173
173
 
174
174
  /**
175
- * @description Counts successful results from a DML operation
175
+ * Counts successful results from a DML operation
176
176
  * @param results List of Database.SaveResult
177
177
  * @return Count of successful operations
178
178
  */
@@ -195,7 +195,7 @@ public with sharing class AccountService {
195
195
  // ─── Exception ───────────────────────────────────────────────────────
196
196
 
197
197
  /**
198
- * @description Custom exception for AccountService errors
198
+ * Custom exception for AccountService errors
199
199
  */
200
200
  public class AccountServiceException extends Exception {}
201
201
  }
@@ -0,0 +1,30 @@
1
+ # Credits & Acknowledgments
2
+
3
+ This skill was influenced by the [sf-skills](https://github.com/Jaganpro/sf-skills) repository and built upon the collective wisdom of the Salesforce developer community. We gratefully acknowledge the following authors and resources whose ideas, patterns, and best practices have shaped this skill.
4
+
5
+ ---
6
+
7
+ ## Authors & Contributors
8
+
9
+ ### Jag Valaiyapathy (**[Jaganpro)](https://github.com/Jaganpro)**
10
+
11
+ **[sf-skills](https://github.com/Jaganpro/sf-skills)**
12
+
13
+ Key contributions influencing this skill:
14
+
15
+ - Pioneering open-source Salesforce skills for agentic coding tools
16
+ - Apex code generation and review patterns
17
+ - Best practices, anti-patterns, and design patterns reference material
18
+ - Template library for common Apex class types
19
+
20
+ This skill was influenced by the [sf-skills](https://github.com/Jaganpro/sf-skills) repository.
21
+
22
+ ---
23
+
24
+ ## Special Thanks
25
+
26
+ To the entire Salesforce developer community for sharing knowledge, writing blogs, creating open-source tools, and helping each other build better solutions.
27
+
28
+ ---
29
+
30
+ *If we've missed anyone whose work influenced these skills, please let us know so we can add proper attribution.*
@@ -1,108 +1,199 @@
1
1
  ---
2
2
  name: generating-apex-test
3
- description: Apex test class generation with TestDataFactory patterns, bulk testing (200+ records), mocking strategies, and assertion best practices. Use this skill when the user asks to create, write, or improve Apex test classes, add coverage, build mocks, or implement testing patterns for triggers, services, batch jobs, queueables, and integrations.
3
+ description: Generate and validate Apex test classes with TestDataFactory patterns, bulk testing (251+ records), mocking strategies, assertion best practices, and disciplined test-fix loops. Use this skill when creating new Apex test classes, improving test coverage, debugging and fixing failing Apex tests, running test execution and coverage analysis, or implementing testing patterns for triggers, services, controllers, batch jobs, queueables, and integrations. Triggers on *Test.cls, *_Test.cls files, sf apex run test workflows, coverage reports, test-fix loops. Do NOT trigger for production Apex code (use generating-apex) or Jest/LWC tests.
4
4
  ---
5
5
 
6
- # Apex Test Class Skill
6
+ # Generating Apex Tests
7
+
8
+ Generate production-ready Apex test classes and run disciplined test-fix loops with coverage analysis.
7
9
 
8
10
  ## Core Principles
9
11
 
10
- 1. **Bulkify tests** - Always test with 200+ records to catch governor limit issues
11
- 2. **Isolate test data** - Use `@TestSetup` and TestDataFactory; never rely on org data
12
- 3. **Assert meaningfully** - Test behavior, not just coverage; include failure messages
13
- 4. **Mock external dependencies** - Use `HttpCalloutMock`, `Test.setMock()` for integrations
14
- 5. **Test negative paths** - Validate error handling, not just happy paths
12
+ 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
13
+ 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](references/async-testing.md)
14
+ 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](references/test-data-factory.md)
15
+ 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](references/assertion-patterns.md)
16
+ 5. **Use `Assert` class only** `Assert.areEqual`, `Assert.isTrue`, `Assert.fail`, etc. Never use legacy `System.assert`, `System.assertEquals`, or `System.assertNotEquals`
17
+ 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](references/mocking-patterns.md)
18
+ 7. **Test negative paths** — validate error handling and exception scenarios, not just happy paths
19
+ 8. **Wrap with start/stop** — pair `Test.startTest()` with `Test.stopTest()` to reset governor limits and force async execution
20
+
21
+ ## Test.startTest() / Test.stopTest()
22
+
23
+ Always wrap the code under test in `Test.startTest()` / `Test.stopTest()`:
24
+
25
+ - Resets governor limits so the test measures only the code under test
26
+ - Executes async operations synchronously (queueables, batch, future methods)
27
+ - Fires scheduled jobs immediately
28
+
29
+ ## Test Code Anti-Patterns
30
+
31
+ | Anti-Pattern | Fix |
32
+ |---|---|
33
+ | SOQL/DML inside loops | Query once before the loop; use `Map<Id, SObject>` for lookups |
34
+ | Magic numbers in assertions | Derive expected values from setup constants |
35
+ | God test class (>500 lines) | Split into multiple test classes by behavior area |
36
+ | Long test methods (>30 lines) | Extract Given/When/Then into helper methods |
37
+ | Generic `Exception` catch | Catch the specific expected type (e.g., `DmlException`) |
38
+
39
+ ## Workflow
40
+
41
+ ### Step 1 — Gather Context
42
+
43
+ Before generating or fixing tests, identify:
44
+
45
+ - the target production class(es) under test
46
+ - existing test classes, test data factories, and setup helpers
47
+ - desired test scope (single class, specific methods, suite, or local tests)
48
+ - coverage threshold (75% minimum for deploy, 90%+ recommended)
49
+ - org alias when running tests against an org
15
50
 
16
- ## Test Class Structure
51
+ ### Step 2 — Generate the Test Class
52
+
53
+ Apply the structure, naming conventions, and patterns from the asset templates and reference docs.
54
+
55
+ **MANDATORY — File Deliverables:** For every test class, create BOTH files:
56
+ 1. `{ClassName}Test.cls` — the test class (use [assets/test-class-template.cls](assets/test-class-template.cls) as starting point)
57
+ 2. `{ClassName}Test.cls-meta.xml` — the metadata file:
58
+
59
+ ```xml
60
+ <?xml version="1.0" encoding="UTF-8"?>
61
+ <ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
62
+ <apiVersion>66.0</apiVersion>
63
+ <status>Active</status>
64
+ </ApexClass>
65
+ ```
66
+
67
+ If no `TestDataFactory` exists in the project, create `TestDataFactory.cls` + `TestDataFactory.cls-meta.xml` using [assets/test-data-factory-template.cls](assets/test-data-factory-template.cls).
68
+
69
+ #### @TestSetup Example
70
+
71
+ ```apex
72
+ @TestSetup
73
+ static void setupTestData() {
74
+ List<Account> accounts = TestDataFactory.createAccounts(251, true);
75
+ }
76
+ ```
77
+
78
+ #### Test Method Structure
79
+
80
+ Use Given/When/Then:
17
81
 
18
82
  ```apex
19
83
  @isTest
20
- private class MyServiceTest {
84
+ static void shouldUpdateStatus_WhenValidInput() {
85
+ // Given
86
+ List<Account> accounts = [SELECT Id FROM Account];
87
+
88
+ // When
89
+ Test.startTest();
90
+ MyService.processAccounts(accounts);
91
+ Test.stopTest();
92
+
93
+ // Then
94
+ List<Account> updated = [SELECT Id, Status__c FROM Account];
95
+ Assert.areEqual(251, updated.size(), 'All accounts should be processed');
96
+ }
97
+ ```
21
98
 
22
- @TestSetup
23
- static void setupTestData() {
24
- // Create shared test data using TestDataFactory
25
- List<Account> accounts = TestDataFactory.createAccounts(200, true);
26
- }
99
+ #### Negative Test — Exception Pattern
27
100
 
28
- @isTest
29
- static void shouldPerformExpectedBehavior_WhenValidInput() {
30
- // Given: Setup specific test state
31
- List<Account> accounts = [SELECT Id, Name FROM Account];
32
-
33
- // When: Execute the code under test
34
- Test.startTest();
35
- MyService.processAccounts(accounts);
36
- Test.stopTest();
37
-
38
- // Then: Assert expected outcomes
39
- List<Account> updated = [SELECT Id, Status__c FROM Account];
40
- System.assertEquals(200, updated.size(), 'All accounts should be processed');
41
- for (Account acc : updated) {
42
- System.assertEquals('Processed', acc.Status__c, 'Status should be updated');
43
- }
44
- }
101
+ Use try/catch with `Assert.fail` to verify expected exceptions:
45
102
 
46
- @isTest
47
- static void shouldThrowException_WhenInvalidInput() {
48
- // Given
49
- List<Account> emptyList = new List<Account>();
50
-
51
- // When/Then
52
- Test.startTest();
53
- try {
54
- MyService.processAccounts(emptyList);
55
- System.assert(false, 'Expected MyCustomException to be thrown');
56
- } catch (MyCustomException e) {
57
- System.assert(e.getMessage().contains('cannot be empty'),
58
- 'Exception message should indicate empty input');
59
- }
60
- Test.stopTest();
103
+ ```apex
104
+ @isTest
105
+ static void shouldThrowException_WhenInvalidInput() {
106
+ // Given
107
+ List<Account> emptyList = new List<Account>();
108
+
109
+ // When/Then
110
+ Test.startTest();
111
+ try {
112
+ MyService.processAccounts(emptyList);
113
+ Assert.fail('Expected MyCustomException to be thrown');
114
+ } catch (MyCustomException e) {
115
+ Assert.isTrue(e.getMessage().contains('cannot be empty'),
116
+ 'Exception message should indicate empty input');
61
117
  }
118
+ Test.stopTest();
62
119
  }
63
120
  ```
64
121
 
65
- ## Naming Convention
122
+ #### Naming Convention
66
123
 
67
- Use descriptive method names: `should[ExpectedBehavior]_When[Condition]`
124
+ - `should[ExpectedResult]_When[Scenario]`: `shouldSendNotification_WhenOpportunityClosedWon`
125
+ - `[SubjectOrAction]_[Scenario]_[ExpectedResult]`: `AccountUpdate_ChangeName_Success`
68
126
 
69
- Examples:
70
- - `shouldCreateContact_WhenAccountIsActive`
71
- - `shouldThrowException_WhenEmailIsInvalid`
72
- - `shouldSendNotification_WhenOpportunityClosedWon`
73
- - `shouldBypassTrigger_WhenRunningAsBatch`
127
+ ### Step 3 — Run Tests
74
128
 
75
- ## Test.startTest() / Test.stopTest()
129
+ Start narrow when debugging; widen after the fix is stable.
76
130
 
77
- Always wrap the code under test:
78
- - Resets governor limits for accurate limit testing
79
- - Executes async operations synchronously (queueables, batch, future)
80
- - Fires scheduled jobs immediately
131
+ ```bash
132
+ # Single test class
133
+ sf apex run test --class-names MyServiceTest --result-format human --code-coverage --target-org <alias>
81
134
 
82
- ## Asset Templates
135
+ # Specific test methods
136
+ sf apex run test --tests MyServiceTest.shouldUpdateStatus_WhenValidInput --result-format human --target-org <alias>
83
137
 
84
- Ready-to-use scaffolds for common test patterns:
138
+ # All local tests
139
+ sf apex run test --test-level RunLocalTests --result-format human --code-coverage --target-org <alias>
140
+ ```
85
141
 
86
- - **[assets/test-class-template.cls](assets/test-class-template.cls)** - Starter test class with positive, negative, bulk, and governor limit test stubs
87
- - **[assets/test-data-factory-template.cls](assets/test-data-factory-template.cls)** - TestDataFactory with Account, Contact, Opportunity, User factories and field override support
142
+ ### Step 4 Analyze Results
88
143
 
89
- ## Reference Files
144
+ Focus on:
90
145
 
91
- Detailed patterns for specific scenarios:
146
+ - failing methods exception types and stack traces
147
+ - uncovered lines and weak coverage areas
148
+ - whether failures indicate bad test data, brittle assertions, or broken production logic
92
149
 
93
- - **[references/test-data-factory.md](references/test-data-factory.md)** - TestDataFactory class patterns and field defaults
94
- - **[references/assertion-patterns.md](references/assertion-patterns.md)** - Assertion best practices and common pitfalls
95
- - **[references/mocking-patterns.md](references/mocking-patterns.md)** - HttpCalloutMock, Test.setMock(), stubbing
96
- - **[references/async-testing.md](references/async-testing.md)** - Batch, Queueable, Future, Scheduled job testing
150
+ ### Step 5 Fix Loop
97
151
 
98
- ## Quick Reference: What to Test
152
+ When tests fail, run a disciplined fix loop (max 3 iterations — stop and surface root cause if still failing):
153
+
154
+ 1. Read the failing test class and the class under test
155
+ 2. Identify root cause from error messages and stack traces
156
+ 3. Apply fix — adjust test data or assertions for test-side issues; delegate production code issues to the `generating-apex` skill
157
+ 4. Rerun the focused test before broader regression
158
+ 5. Repeat until all tests pass, iteration limit reached, or root cause requires design change
159
+
160
+ ### Step 6 — Validate Coverage
161
+
162
+ | Level | Coverage | Purpose |
163
+ |-------|----------|---------|
164
+ | Production deploy | 75% minimum | Required by Salesforce |
165
+ | Recommended | 90%+ | Best practice target |
166
+ | Critical paths | 100% | Business-critical code |
167
+
168
+ Cover all paths: positive, negative/exception, bulk (251+ records), callout/async.
169
+
170
+ ## What to Test by Component
99
171
 
100
172
  | Component | Key Test Scenarios |
101
173
  |-----------|-------------------|
102
- | Trigger | Bulk insert/update/delete, recursion, field changes |
103
- | Service | Valid/invalid inputs, bulk operations, exceptions |
174
+ | Trigger | Bulk insert/update/delete, recursion guard, field change detection |
175
+ | Service | Valid/invalid inputs, bulk operations, exception handling |
104
176
  | Controller | Page load, action methods, view state |
105
- | Batch | Start/execute/finish, chunking, error records |
106
- | Queueable | Chaining, bulkification, error handling |
177
+ | Batch | start/execute/finish, scope matching (batch size >= record count), `Database.Stateful` tracking, error handling, chaining (separate methods — `finish()` calling `Database.executeBatch()` throws `UnexpectedException`) |
178
+ | Queueable | Chaining (only first job runs in tests), bulkification, error handling, callout mocks before `Test.startTest()` |
107
179
  | Callout | Success response, error response, timeout |
108
- | Scheduled | Execution, CRON validation |
180
+ | Selector | Valid/null/empty inputs, bulk (251+), field population, sort order, `WITH USER_MODE` via `System.runAs` |
181
+ | Scheduled | Direct execution via `execute(null)`, CRON registration via `CronTrigger` query |
182
+ | Platform Event | `Test.enableChangeDataCapture()`, `Test.getEventBus().deliver()`, verify subscriber side effects |
183
+
184
+ ## Output Expectations
185
+
186
+ Deliverables per test class:
187
+ - `{ClassName}Test.cls` + `{ClassName}Test.cls-meta.xml` (match API version of class under test; default `66.0`)
188
+ - `TestDataFactory.cls` + `TestDataFactory.cls-meta.xml` (if not already present)
189
+
190
+ ## Reference Files
191
+
192
+ Load on demand for detailed patterns:
193
+
194
+ | Reference | When to use |
195
+ |-----------|-------------|
196
+ | [references/test-data-factory.md](references/test-data-factory.md) | TestDataFactory patterns, field overrides, duplicate rule handling |
197
+ | [references/assertion-patterns.md](references/assertion-patterns.md) | Assertion best practices, anti-patterns, common pitfalls |
198
+ | [references/mocking-patterns.md](references/mocking-patterns.md) | HttpCalloutMock, DML mocking, StubProvider, SOSL, Email, Platform Events |
199
+ | [references/async-testing.md](references/async-testing.md) | Batch, Queueable, Future, Scheduled job testing |
@@ -1,51 +1,47 @@
1
1
  /**
2
2
  * @description Test class for {ClassUnderTest}.
3
- * Tests bulk operations (200+ records), positive/negative paths,
3
+ * Tests bulk operations (251+ records), positive/negative paths,
4
4
  * and exception handling.
5
- * @author Generated by Apex Test Writer Skill
6
5
  */
7
6
  @isTest
8
7
  private class {ClassUnderTest}Test {
9
8
 
10
- // ─── Test Setup ───────────────────────────────────────────────────────
11
-
12
9
  @TestSetup
13
10
  static void setupTestData() {
14
- // Create shared test data using TestDataFactory
15
- // List<Account> accounts = TestDataFactory.createAccounts(200, true);
11
+ List<Account> accounts = TestDataFactory.createAccounts(251, true);
16
12
  }
17
13
 
18
14
  // ─── Positive Tests ───────────────────────────────────────────────────
19
15
 
20
16
  @isTest
21
17
  static void shouldPerformExpectedBehavior_WhenValidInput() {
22
- // Given: Setup specific test state
23
- // List<Account> accounts = [SELECT Id, Name FROM Account];
18
+ // Given
19
+ List<Account> accounts = [SELECT Id, Name FROM Account];
24
20
 
25
- // When: Execute the code under test
21
+ // When
26
22
  Test.startTest();
27
23
  // {ClassUnderTest}.methodUnderTest(params);
28
24
  Test.stopTest();
29
25
 
30
- // Then: Assert expected outcomes
31
- // System.assertEquals(expected, actual, 'Descriptive failure message');
26
+ // Then
27
+ // Assert.areEqual(expected, actual, 'Descriptive failure message');
32
28
  }
33
29
 
34
30
  @isTest
35
- static void shouldHandleBulkRecords_WhenProcessing200() {
36
- // Given: 200+ records to verify bulkification
37
- // List<Account> accounts = [SELECT Id FROM Account];
38
- // System.assertEquals(200, accounts.size(), 'Should have 200 test records');
31
+ static void shouldHandleBulkRecords_WhenProcessing251() {
32
+ // Given
33
+ List<Account> accounts = [SELECT Id FROM Account];
34
+ Assert.areEqual(251, accounts.size(), 'Should have 251 test records');
39
35
 
40
36
  // When
41
37
  Test.startTest();
42
38
  // {ClassUnderTest}.bulkMethod(accounts);
43
39
  Test.stopTest();
44
40
 
45
- // Then: Verify all records processed
41
+ // Then
46
42
  // List<Account> results = [SELECT Id, Status__c FROM Account];
47
43
  // for (Account acc : results) {
48
- // System.assertEquals('Processed', acc.Status__c, 'All records should be processed');
44
+ // Assert.areEqual('Processed', acc.Status__c, 'All records should be processed');
49
45
  // }
50
46
  }
51
47
 
@@ -53,21 +49,15 @@ private class {ClassUnderTest}Test {
53
49
 
54
50
  @isTest
55
51
  static void shouldThrowException_WhenNullInput() {
56
- Boolean exceptionThrown = false;
57
- String exceptionMessage = '';
58
-
59
52
  Test.startTest();
60
53
  try {
61
54
  // {ClassUnderTest}.methodUnderTest(null);
62
- } catch (Exception e) {
63
- exceptionThrown = true;
64
- exceptionMessage = e.getMessage();
55
+ Assert.fail('Expected exception for null input');
56
+ } catch (MyCustomException e) {
57
+ Assert.isTrue(e.getMessage().contains('cannot be null'),
58
+ 'Exception message should mention null input');
65
59
  }
66
60
  Test.stopTest();
67
-
68
- System.assert(exceptionThrown, 'Exception should be thrown for null input');
69
- System.assert(exceptionMessage.contains('cannot be null'),
70
- 'Exception message should mention null input');
71
61
  }
72
62
 
73
63
  @isTest
@@ -76,16 +66,16 @@ private class {ClassUnderTest}Test {
76
66
  // List<SObject> results = {ClassUnderTest}.methodUnderTest(new List<Id>());
77
67
  Test.stopTest();
78
68
 
79
- // System.assert(results.isEmpty(), 'Should return empty list for empty input');
69
+ // Assert.isTrue(results.isEmpty(), 'Should return empty list for empty input');
80
70
  }
81
71
 
82
72
  // ─── Edge Case Tests ──────────────────────────────────────────────────
83
73
 
84
74
  @isTest
85
75
  static void shouldHandleMixedRecords_WhenSomeQualify() {
86
- // Given: Mix of qualifying and non-qualifying records
87
- // List<Account> accounts = [SELECT Id, Status__c FROM Account];
88
- // Integer half = accounts.size() / 2;
76
+ // Given
77
+ List<Account> accounts = [SELECT Id, Status__c FROM Account];
78
+ Integer half = accounts.size() / 2;
89
79
  // for (Integer i = 0; i < half; i++) {
90
80
  // accounts[i].Status__c = 'Qualifying';
91
81
  // }
@@ -96,29 +86,8 @@ private class {ClassUnderTest}Test {
96
86
  // {ClassUnderTest}.conditionalMethod(accounts);
97
87
  Test.stopTest();
98
88
 
99
- // Then: Only qualifying records should be affected
89
+ // Then
100
90
  // List<Account> qualifying = [SELECT Id FROM Account WHERE Processed__c = true];
101
- // System.assertEquals(half, qualifying.size(), 'Only qualifying records should be processed');
102
- }
103
-
104
- // ─── Governor Limit Tests ─────────────────────────────────────────────
105
-
106
- @isTest
107
- static void shouldNotExceedGovernorLimits_WhenBulkProcessing() {
108
- // Given
109
- // List<Account> accounts = [SELECT Id FROM Account];
110
-
111
- Test.startTest();
112
- // {ClassUnderTest}.heavyMethod(accounts);
113
- Test.stopTest();
114
-
115
- System.assert(Limits.getDmlStatements() < Limits.getLimitDmlStatements(),
116
- 'Should not exceed DML statement limit');
117
- System.assert(Limits.getQueries() < Limits.getLimitQueries(),
118
- 'Should not exceed SOQL query limit');
91
+ // Assert.areEqual(half, qualifying.size(), 'Only qualifying records should be processed');
119
92
  }
120
-
121
- // ─── Helper Methods ───────────────────────────────────────────────────
122
-
123
- // Add test-specific helper methods here
124
93
  }
@@ -2,7 +2,6 @@
2
2
  * @description Centralized factory for creating test data with sensible defaults.
3
3
  * All methods accept a doInsert flag for flexibility.
4
4
  * Bulk methods create multiple records; single-record methods delegate to bulk.
5
- * @author Generated by Apex Test Writer Skill
6
5
  */
7
6
  @isTest
8
7
  public class TestDataFactory {