When testing, how/when will @TestSetup annotation be preferable to a "DataFactory"?

I understand how both works, but I don't see any case where I'd rather use the @testSetup annotation.

I use this datafactory and it works very well.

  • 2
    avinash's answer is more to the point. @testSetup and a dataFactory are not mutually exclusive. They can (and should) be used together more times than not.
    – willard
    Oct 19 '18 at 14:10

A major reason to use @TestSetup is the situation where you have many tests that require the same baseline of data. The @TestSetup method runs once and all its data is available to all the test methods in the class. Any changes made by a test method are rolled back but the @TestSetup data isn't. The benefit is faster test running because the baseline data inserts are only done once per test class not once per test method.

A downside is that the only way to get references to the data created in @TestSetup is to query for it. But those queries are much cheaper than the inserts.

(The @TestSetup method also gets its own set of governor limits, so if you have a lot of data setup logic that consumes a big proportion of those, moving it to @TestSetup will help.)

I use @TestSetup sometimes, and other times, when I want to refer to the test data in the following asserts, use builder classes invoked from each test method so I have references to the test objects without having to do queries.

You can choose to use whatever technique you like to create the SObjects and use that method inside the @TestStup method or outside of it.

Some more information on @TestSetup: What are the advantage of the @testSetUp annotation.


I use both. Why would you have to choose one over the other? @testSetup is a way to reduce test execution time by reusing the data created once in all the test methods of a test class.

TestFactory is to reuse same data in multiple test classes.


private class AvinashTest {
    static void testSetup() {
        Account a = (Account) TestFactory.createSObject(new Account(), true);
        a.Oracle_Cust_Number__c  = '10';
        update a;
        Brand__c b = (Brand__c) TestFactory.createSObject(new Brand__c(), true);
        example_Product__c rocProd = TestDataFactory.getexampleProduct( 'Test Prod', b );
        insert rocProd;
        Contact c = (Contact) TestFactory.createSObject(new Contact(), true);
        Opportunity o = (Opportunity) TestFactory.createSObject(new Opportunity(AccountId=a.Id,StageName='Closed Lost', Channel_Type__c = 'Direct'), true);
        Product2 prod1 = (Product2) TestFactory.createSObject(new Product2(Brand__c=b.Id), true);
        prod1.example_Product__c = rocProd.Id;

        update new User(Service_Provider__c = true, Id = UserInfo.getUserId()); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.