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
    Commented Oct 19, 2018 at 14:10

2 Answers 2


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()); 

You must log in to answer this question.

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