10

Let this sample code demonstrate what I mean here:

@isTest
public class TestSample 
{
    public static String tmp;
    @isTest 
    static void Test1()
    {
        System.debug('tmp in Test1: ' + tmp);
    }

    @testSetup
    static void testPrep()
    {
        tmp = 'Hello';
        System.debug('tmp in prep: ' + tmp);
    }
}

Debug result is:

tmp in prep: Hello. tmp in Test1: null

I understand that Salesforce should clear up static variable values after each unit test method run. But it doesn't make much sense to me it should do the same thing after testSetup method is finished.

Is there any particular reason Salesforce is doing so? Or is it a bug of Salesforce?

2
  • 2
    Having them would eliminate the need to query for the records after test setup amount other things
    – Eric
    Sep 14, 2016 at 7:22
  • 2
    Presume the mechanism used to clear statics between test methods is an "all or none" one. The docs are focussed on database changes being preserved: no mention of code values being preserved. (The documentation should probably be more explicut.)
    – Keith C
    Sep 14, 2016 at 7:53

1 Answer 1

8

If you read the docs, you will notice that it doesn't talk about preserving code values. However, it is explicit about the fact that the purpose of test setup methods is to create a common set of records.

Use test setup methods (methods that are annotated with @testSetup) to create test records once and then access them in any test method in the test class. Test setup methods are useful and can be time-saving when you need to create a common set of records that all test methods operate on or prerequisite data.

And, the idea behind clearing static variables is to make the tests data independent. If the static variables aren't cleared, then the tests may produce different results depending on the order in which they execute and state of static variables.

Also, using test setup methods for creating common set of records at once reduces the execution time as the DML operations fire workflows, triggers, validation rules, etc.

Please see this Idea for more details.

5
  • 6
    +1, I still say they should preserve the values (that is my Idea, after all), especially since I recently found they also preserve the governor limits from the testSetup method as well.
    – sfdcfox
    Sep 14, 2016 at 8:16
  • @sfdcfox I agree on this. I would say they should preserve the values for testSetup but clear the values between test methods
    – Lance Shi
    Sep 14, 2016 at 9:21
  • 3
    @sfdcfox Agreed. Having the governor limits used by the @testSetup method apply to each test method was a turn-off for me when the feature was introduced (which made the feature only marginally better than a plain, old static method that I would call at the beginning of each testMethod). Perhaps we could convince Salesforce to compromise and preserve final static variables set in an @testSetup method.
    – Derek F
    Sep 14, 2016 at 14:08
  • 2
    @DerekF After the response from the PM, it kind of made sense, but if I had my way, I'd suggest a new annotation like TestPersistent or something. A variable annotated with some annotation would act like a normal static variable during TestSetup, but act as a final static during each testMethod. I'd expect the usual restrictions, like only allowed in an isTest class, all annotated members must be serializable, cannot be referenced outside an isTest class, etc. It'd be cheap to implement but save so much trouble in the long run.
    – sfdcfox
    Sep 14, 2016 at 15:00
  • I thought every test method ran in its own execution context. If that's the case, then changing the value of a static property would only affect the currently-running test method, not any others. What am I missing? Dec 8, 2017 at 2:05

You must log in to answer this question.

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