9

First of all, sorry that I couldn't frame the question better. But I will try my best to explain why I am asking what I am asking:

  1. There are multiple custom objects like Client_1__c, Client_2__c, ... Client_200__c which all have triggers like Client_1_Manager, Client_2_Manager, ... Client_200_Manager respectively. 200 total different but similar triggers for 200 different but similar objects. (That is how it is, which is not a problem for us.)
  2. (Not sure if this info matters, but, ) All Client_n_Manager triggers ultimately call ONE common class to do something.
  3. Currently, there is one test class for each trigger like Client_1_Manager_Test, Client_2_Manager_Test, ... Client_200_Manager_Test respectively. That is 200 test classes for 200 triggers.

Problem? This setup poses a maintenance issue and a lot of redundancy which I want to fix, at least when it comes to test classes. So: Can [3] above be boiled into ONE test class?

Helpful notes: Fortunately for us, there is an object that has a list of all Client_n__c object names.

Goal: Write ONE test class that inserts, updates, deletes an sObject based of client_n__c type in a loop (or better).

Potentials issues:

  1. Obviously the governor limits for the test class. There will be 200+ triggers/objects.
  2. Also, I remember from my experience that a DML operation on a List that contains more than 10 sObjectTypes fails (can't recollect the exact exception).

First thought: I think the answer to the puzzle would be same as the answer to: Is there a way to execute Test.startTest() and Test.stopTest() in a loop? Doing so will reset the limits for each test run so I can write a generic test method that processes each client trigger. What I mean is, can the below code be tweaked SOMEHOW to make it work because it throws 'System.FinalException: Testing already started' exception:

@isTest
private class Sample_Test {

    static void printTest(Integer i){
        Test.startTest();
        system.debug(logginglevel.ERROR, '$$$$$$$$$$$$$$$$$$$$$$$ ' + i);
        Test.stopTest();
    }

    static testMethod void sample_test_method() {
        for(Integer i = 0; i<= 500; i++)
            printTest(i);
    }
}

Second thought: Could we schedule a test class to run its test methods in batches? That could make it governor-limit friendly. (Note that I am not asking how to write a test class for a scheduled job. It is the other way round.) Would that contribute towards test code coverage at all?

  • you can also do something like create comman method for them one for insert, update and delete (using describe or any other approach) and from you main test method just call these methods. It will also help you to reduce line of code. If you don't have much required field and validation then this method will surely help. – Tushar Sharma May 9 '16 at 16:04
  • 1
    note that test.startTest() and Test.stopTest() are not required in all use cases; obviously, they reset governor limits which may be important to your individual use case and they are needed if async methods are to be executed. If none of these apply, you could do 5-10 sobjects per testmethod and hence reduce #of tests – cropredy May 9 '16 at 16:13
8

Unfortunately, no. While you can have all 200 tests in a single class, you'll still need 200 unit tests. Test.startTest() will throw an exception if it's already been called, and Test.stopTest() will throw an exception if it's already been called.

You can, however, use @testSetup to set up all common data first before running your 200 tests-- they'll only count for the governor limits once and save you execution time (usually by many minutes).

@isTest
private class Sample_Test {

    @testSetup static void testSetup() {
         // Set up common data here
    }

    static void printTest(Integer i){
         // Query your data from testSetup before starting test
        Test.startTest();
        system.debug(logginglevel.ERROR, '$$$$$$$$$$$$$$$$$$$$$$$ ' + i);
        Test.stopTest();
    }

    static testMethod void sample_test_method_1() {
            printTest(1);
    }
    static testMethod void sample_test_method_2() {
            printTest(2);
    }
    static testMethod void sample_test_method_3() {
            printTest(3);
    }
    // ...
}
  • How about my second thought? Could we schedule a test class to run its test methods in batches? – Lightning Evangelist May 9 '16 at 15:38
  • @Kal Unit tests naturally do this when you run unit tests in a class-- each unit test gets its own limits. – sfdcfox May 9 '16 at 15:39
  • Right, that I understand. But I don't want to manually add a new test method each time there is a new Client_n__c object. Could a SchedulableContext somehow help with that? – Lightning Evangelist May 9 '16 at 15:45
  • 1
    @Kal Unfortunately not. The only thing you can do in a SchedulableContext would be to insert ApexTestQueue items, which would only run existing code. Otherwise, any code you ran would be live, wouldn't count for code coverage, and could permanently alter your database data. – sfdcfox May 9 '16 at 15:50
  • @Kal Personally, I think it's a great idea-- you should post an idea. I'll even vote and promote it. – sfdcfox May 9 '16 at 15:52

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.