6

If you create additional test records inside a test method, those records are rolled back at the end of the test method’s execution, which also happens when you’re not using test setup methods.

https://developer.salesforce.com/releases/release/Spring15/TestClasses

2 Answers 2

10

The scenario that @testSetup solves is simple.

Say you have a class that has three methods, all of which take a contact, and do different things. You might write a test for it like this:

@isTest public class ContactRejiggererTest {
    @isTest public static test_contact_rennovate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.rennovate(con);
        System.assertEquals('Building Bridges',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_mediate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.mediate(con);
        System.assertEquals('Zen and Motorcycles',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_deviate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.deviate(con);
        System.assertEquals('The Anarchist's Cookbook',Favorite_Book_Formula__c);
    }
}

There's a lot of code re-use here! We can solve that with a @testSetup!

@isTest public class ContactRejiggererTest {
   @testSetup public static createAl() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;
   }

    @isTest public static test_contact_rennovate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.rennovate(con);
        System.assertEquals('Building Bridges',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_mediate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.mediate(con);
        System.assertEquals('Zen and Motorcycles',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_deviate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.deviate(con);
        System.assertEquals('The Anarchist's Cookbook',Favorite_Book_Formula__c);
    }
}

The contact gets rolled back to it's initial state after each test method.

2
  • 9
    It's not just code reuse. If you have five seconds worth of DML operations for each test, and you want to use isolation, test setup can reduce your total test time by five seconds per each test beyond the first. I literally shaved over 20 minutes off our production deployment time using @TestSetup when it first came out.
    – sfdcfox
    Commented Oct 8, 2015 at 18:39
  • Now if they could add the ability to populate a static property with the ID or a Map<Schema.sObjectType,ID[]> in test setup for use in other test methods it would remove the need to query in each test method just to get the ID of a record to update
    – Eric
    Commented Jul 22, 2016 at 7:20
2

There is also an undocumented limit to the total number of records that can be inserted when running unit tests. Moving to @TestSetup solved this problem for us in our most recent large project.

4

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .