2

As per my understanding and salesforce documentation, class annotated with @isTest should contain "only test methods". But there are some situations where we might need to have utility methods and these cannot be put in test method. For example, consider a requirement where account record has to be inserted by 2 different user profiles. Usually, I create the Account record in the following way:

static Account createAccRec() {
    Account a = new Account();
    a.name = 'test';    
    return a;
}

and then, actual test method looks like this:

@isTest
static void createAccountasAgent1() {
    user agent1 = [select id from user where profile.name = 'agent1' and isActive=true Limit 1];
    system.runAs(agent1) {
        insert a;
    }
    system.assertEquals(null, [select id from account where name='test'].Id);
}

@isTest
static void createAccountasAgent2() {
    user agent1 = [select id from user where profile.name = 'agent2' and isActive=true Limit 1];
    system.runAs(agent2) {
        insert a;
    }
    system.assertNotEquals(null, [select id from account where name='test'].Id);
}

So, now this test class has 2 proper test methods and one static utility method to create data. Not sure if this will affect over all code usage but I tried to modify the non test method using @TestSetup as follows so that now this test class has only test methods:

@testsetup
static void createAccount() {
    Account a = new Account();
    a.name = 'test';
}

However, using @TestSetup followed by actual test method does not work and throws an error:

Variable does not exist : a

Is there a way to overcome this issue?

1 Answer 1

3

I disagree strongly with your assessment of how @IsTest annotated classes should work.

As per my understanding and salesforce documentation, class annotated with "@isTest" sshould [sic] have "only test methods".

As you note, you need to be able to write test utilities. For example the following is perfectly acceptable:

@IsTest
public with sharing class AccountTestUtility
{
    public Account buildAccountWithName(String name)
    {
        return new Account(Name=name);
    }
}

It could certainly be made more generic and flexible, but there's no problem with the method not being a test method.


As for coverage, the R&D team should be working on fixing this Known Issue: Non-test methods in a test class are counted as part of Apex code Coverage. Note, however, that @TestSetup annotation is not a workaround, and suffers the same limitation (bug).


Regardless, when you use @TestSetup, the only thing you can do is create records that will exist when your tests run. Static and instance variables you set in this method will not still be set when your tests run.

If you would like to make it possible to have static variables you can set from @TestSetup methods, vote for this Idea: Remember static variables set during testSetup annotated methods.

However, it looks unlikely to be released. The last comment from the product team:

We intentionally clear out static variables between each test method. If we did not, each test would cease to be an independent trial. You could modify the static in one test method, which would make the order in which tests operate relevant to the results. This is precisely what you don't want - data dependent tests.

If you want information that is common to all tests, it can be inserted in the test setup method and queried in each test method. The idea here is not to reduce the number of SOQL queries, it is to reduce the amount of data being inserted into the system. If you insert 1000 records in test setup, run fifteen test methods, and you run a query 15 times to get the 1000 records each time, that's still less expensive (and faster) than inserting 1000 records 15 times.

3
  • Thanks Adrian. So do you think if there will be any affect on "percent of Apex Used" when using static methods with no test annotation inside actual test class ?
    – sf_user
    Commented Oct 20, 2016 at 20:18
  • No, there will not be any effect. There have been some bugs reported around it in the developer console, but they are just that - bugs. And I don't think they actually count against you. Besides, the @TestSetup annotation doesn't exempt you from that bug. See this Known Issue.
    – Adrian Larson
    Commented Oct 20, 2016 at 20:19
  • 1
    If you didn't mention that static helper methods have a place in test classes, I would have. Having such a method is useful for keeping the queries (that we have to make to get at the data created in @testSetup) in one place. Also presents a good opportunity to re-populate static variables.
    – Derek F
    Commented Oct 20, 2016 at 20:30

You must log in to answer this question.

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