Name the behavior. Arrange the data. Assert the result.
Start with a useful failure message
A test called testMethod1 tells you almost nothing when it fails. A test called preservesExistingDescription names a promise. Put the promise in the assertion message as well.
Create the data the test needs. Use @TestSetup when several tests share a baseline, then query that fixture within each test. This keeps the example independent of records someone happened to create in an org. Salesforce covers the pattern in its test data guide.
Test the contract, across a batch
This companion to our ContactAccountNote trigger verifies the result for 200 contacts. It requires that trigger, a practice org, and a running user who can access the fields used by its user-mode query. Adapt fixtures for any additional validation rules in your org.
@IsTest
private class ContactAccountNoteTest {
@TestSetup
static void arrangeAccounts() {
insert new Account(Name = 'Sample Workshop');
}
@IsTest
static void fillsDescriptionsAcrossABatch() {
Account company = [SELECT Id, Name FROM Account LIMIT 1];
List<Contact> people = new List<Contact>();
for (Integer i = 0; i < 200; i++) {
people.add(new Contact(
LastName = 'Reader ' + i, AccountId = company.Id
));
}
Test.startTest();
insert people;
Test.stopTest();
List<Contact> saved = [
SELECT Description FROM Contact
WHERE AccountId = :company.Id
];
Assert.areEqual(200, saved.size(), 'Save the whole batch');
for (Contact person : saved) {
Assert.areEqual(
'Account: Sample Workshop', person.Description,
'Every contact receives the account note'
);
}
}
}Add the cases that change the answer
Keep setup outside Test.startTest() and put the operation under test inside the start/stop window. That gives the operation its own governor-limit context. Assert the observable result afterward; Salesforce's testing walkthrough explains this arrangement.
Next, write preservesExistingDescription with a prefilled description, and ignoresContactsWithoutAccounts with a null account. Neither case should receive the generated note. A permission-focused test belongs alongside them because the production query intentionally respects user access.
These tests answer three different questions. Keeping them separate makes a failure much easier to interpret than one large test with a dozen unrelated expectations.
Go a little deeper.
Official references behind this note:
Examples are for learning. Validate them in a practice org against your API version, permissions, validation rules, and existing automation.