mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 03:09:50 +08:00
* Migrating Core Salesforce Skills * Updating pr comments * updat reference * Updating a skill * Migrating Datacloud skills * Migrating Industries cloud skills * Validating - skills fixing --------- Co-authored-by: Sandip Kumar Yadav <sandipkumar.yadav+sfemu@salesforce.com>
256 lines
11 KiB
OpenEdge ABL
256 lines
11 KiB
OpenEdge ABL
/**
|
|
* @description Bulk testing template for trigger and service validation
|
|
* Tests with 251+ records to ensure bulkification compliance.
|
|
* 251 records crosses the 200-record trigger batch boundary.
|
|
* @created {{Date}}
|
|
*/
|
|
@IsTest
|
|
private class {{ClassName}}BulkTest {
|
|
|
|
// Record counts for different test scenarios
|
|
private static final Integer BULK_SIZE = 251; // Crosses 200-batch boundary
|
|
private static final Integer LARGE_BULK_SIZE = 501; // Multiple batch boundaries
|
|
private static final Integer SINGLE_BATCH = 200; // Single batch (edge case)
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// BULK INSERT TESTS
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Tests bulk insert with 251 records
|
|
* Verifies trigger handles multiple batch chunks correctly
|
|
*/
|
|
@IsTest
|
|
static void testBulkInsert_251Records_AllProcessed() {
|
|
// GIVEN
|
|
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
|
|
// WHEN
|
|
Test.startTest();
|
|
Database.SaveResult[] results = Database.insert(records, false);
|
|
Test.stopTest();
|
|
|
|
// THEN - All records should be successfully inserted
|
|
Integer successCount = 0;
|
|
Integer failCount = 0;
|
|
for (Database.SaveResult sr : results) {
|
|
if (sr.isSuccess()) {
|
|
successCount++;
|
|
} else {
|
|
failCount++;
|
|
System.debug('Insert failed: ' + sr.getErrors()[0].getMessage());
|
|
}
|
|
}
|
|
|
|
Assert.areEqual(BULK_SIZE, successCount,
|
|
'All ' + BULK_SIZE + ' records should insert successfully');
|
|
Assert.areEqual(0, failCount, 'No records should fail');
|
|
|
|
// Verify governor limits
|
|
assertGovernorLimitsNotExceeded();
|
|
}
|
|
|
|
/**
|
|
* @description Tests bulk insert at exact batch boundary (200 records)
|
|
*/
|
|
@IsTest
|
|
static void testBulkInsert_ExactBatchSize_AllProcessed() {
|
|
// GIVEN
|
|
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(SINGLE_BATCH);
|
|
|
|
// WHEN
|
|
Test.startTest();
|
|
insert records;
|
|
Test.stopTest();
|
|
|
|
// THEN
|
|
Integer count = [SELECT COUNT() FROM {{ObjectName}}];
|
|
Assert.areEqual(SINGLE_BATCH, count,
|
|
'All ' + SINGLE_BATCH + ' records should be inserted');
|
|
assertGovernorLimitsNotExceeded();
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// BULK UPDATE TESTS
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Tests bulk update with 251 records
|
|
* Verifies update triggers handle multiple batches
|
|
*/
|
|
@IsTest
|
|
static void testBulkUpdate_251Records_AllUpdated() {
|
|
// GIVEN - Insert records first
|
|
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
insert records;
|
|
|
|
// Modify all records
|
|
for ({{ObjectName}} rec : records) {
|
|
// TODO: Update fields that trigger logic
|
|
// rec.SomeField__c = 'Updated Value';
|
|
}
|
|
|
|
// WHEN
|
|
Test.startTest();
|
|
Database.SaveResult[] results = Database.update(records, false);
|
|
Test.stopTest();
|
|
|
|
// THEN
|
|
Integer successCount = 0;
|
|
for (Database.SaveResult sr : results) {
|
|
if (sr.isSuccess()) {
|
|
successCount++;
|
|
}
|
|
}
|
|
|
|
Assert.areEqual(BULK_SIZE, successCount,
|
|
'All ' + BULK_SIZE + ' records should update successfully');
|
|
assertGovernorLimitsNotExceeded();
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// BULK DELETE TESTS
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Tests bulk delete with 251 records
|
|
* Verifies delete triggers handle cleanup correctly
|
|
*/
|
|
@IsTest
|
|
static void testBulkDelete_251Records_AllDeleted() {
|
|
// GIVEN
|
|
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(BULK_SIZE);
|
|
insert records;
|
|
|
|
// WHEN
|
|
Test.startTest();
|
|
Database.DeleteResult[] results = Database.delete(records, false);
|
|
Test.stopTest();
|
|
|
|
// THEN
|
|
Integer successCount = 0;
|
|
for (Database.DeleteResult dr : results) {
|
|
if (dr.isSuccess()) {
|
|
successCount++;
|
|
}
|
|
}
|
|
|
|
Assert.areEqual(BULK_SIZE, successCount,
|
|
'All ' + BULK_SIZE + ' records should delete successfully');
|
|
|
|
Integer remainingCount = [SELECT COUNT() FROM {{ObjectName}}];
|
|
Assert.areEqual(0, remainingCount, 'No records should remain');
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// MIXED DML BULK TESTS
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Tests mixed operations in bulk
|
|
* Verifies partial success scenarios are handled
|
|
*/
|
|
@IsTest
|
|
static void testBulkMixedOperations_PartialSuccess() {
|
|
// GIVEN - Some valid, some invalid records
|
|
List<{{ObjectName}}> validRecords = TestDataFactory.create{{ObjectName}}s(200);
|
|
List<{{ObjectName}}> invalidRecords = new List<{{ObjectName}}>();
|
|
|
|
// Create invalid records (missing required fields or validation failures)
|
|
for (Integer i = 0; i < 51; i++) {
|
|
invalidRecords.add(new {{ObjectName}}(
|
|
// TODO: Set up record that will fail validation
|
|
));
|
|
}
|
|
|
|
List<{{ObjectName}}> allRecords = new List<{{ObjectName}}>();
|
|
allRecords.addAll(validRecords);
|
|
allRecords.addAll(invalidRecords);
|
|
|
|
// WHEN - Insert with allOrNone = false
|
|
Test.startTest();
|
|
Database.SaveResult[] results = Database.insert(allRecords, false);
|
|
Test.stopTest();
|
|
|
|
// THEN - Count successes and failures
|
|
Integer successCount = 0;
|
|
Integer failCount = 0;
|
|
for (Database.SaveResult sr : results) {
|
|
if (sr.isSuccess()) {
|
|
successCount++;
|
|
} else {
|
|
failCount++;
|
|
}
|
|
}
|
|
|
|
// Verify partial success handled correctly
|
|
Assert.isTrue(successCount > 0, 'Some records should succeed');
|
|
// Note: Uncomment if you expect failures
|
|
// Assert.isTrue(failCount > 0, 'Some records should fail validation');
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// GOVERNOR LIMIT VERIFICATION
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Helper method to verify governor limits not exceeded
|
|
* Call after Test.stopTest() to check limit usage
|
|
*/
|
|
private static void assertGovernorLimitsNotExceeded() {
|
|
// SOQL Queries (limit: 100)
|
|
Assert.isTrue(Limits.getQueries() < 90,
|
|
'SOQL queries approaching limit: ' + Limits.getQueries() + '/100');
|
|
|
|
// DML Statements (limit: 150)
|
|
Assert.isTrue(Limits.getDmlStatements() < 140,
|
|
'DML statements approaching limit: ' + Limits.getDmlStatements() + '/150');
|
|
|
|
// DML Rows (limit: 10,000)
|
|
Assert.isTrue(Limits.getDmlRows() < 9500,
|
|
'DML rows approaching limit: ' + Limits.getDmlRows() + '/10000');
|
|
|
|
// Heap Size (limit: 6MB sync, 12MB async)
|
|
Assert.isTrue(Limits.getHeapSize() < 5000000,
|
|
'Heap size approaching limit: ' + Limits.getHeapSize() + '/6000000');
|
|
|
|
// CPU Time (limit: 10,000ms sync, 60,000ms async)
|
|
Assert.isTrue(Limits.getCpuTime() < 9000,
|
|
'CPU time approaching limit: ' + Limits.getCpuTime() + '/10000');
|
|
|
|
System.debug('═══════════════════════════════════════════════════════');
|
|
System.debug('GOVERNOR LIMIT USAGE:');
|
|
System.debug(' SOQL Queries: ' + Limits.getQueries() + '/100');
|
|
System.debug(' DML Statements: ' + Limits.getDmlStatements() + '/150');
|
|
System.debug(' DML Rows: ' + Limits.getDmlRows() + '/10000');
|
|
System.debug(' Heap Size: ' + Limits.getHeapSize() + '/6000000');
|
|
System.debug(' CPU Time: ' + Limits.getCpuTime() + 'ms /10000ms');
|
|
System.debug('═══════════════════════════════════════════════════════');
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// STRESS TESTS (Optional - Run sparingly)
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @description Stress test with 501 records (multiple batch boundaries)
|
|
* Use sparingly - consumes significant test execution time
|
|
*/
|
|
@IsTest
|
|
static void testStressTest_501Records_AllProcessed() {
|
|
// GIVEN
|
|
List<{{ObjectName}}> records = TestDataFactory.create{{ObjectName}}s(LARGE_BULK_SIZE);
|
|
|
|
// WHEN
|
|
Test.startTest();
|
|
insert records;
|
|
Test.stopTest();
|
|
|
|
// THEN
|
|
Integer count = [SELECT COUNT() FROM {{ObjectName}}];
|
|
Assert.areEqual(LARGE_BULK_SIZE, count,
|
|
'All ' + LARGE_BULK_SIZE + ' records should be processed');
|
|
assertGovernorLimitsNotExceeded();
|
|
}
|
|
}
|