1

I've started a new job and the test code coverage here is poor.

I am working to improve this and one of the batch classes has coverage of 77% in production. This is now below the org % so I thought I'd get a quick win.

The Full sandbox was refreshed recently so I go to see if I can fix the 3 lines not being tested. Looks easy.

BUT

In Full the coverage is 27%. The classes are identical. The scheduled classes are identical. The test classes are identical (I even removed all my debug messages)

In Full it seems that the tests stop at the Execute() method. Debug logs show that everything up to that point works fine, test Leads are inserted. IDs correspond at each end of the process.

What am I missing? Why would tests be better in Prod than in Sandbox?

Class:

GLOBAL CLASS Update_IC_CampaignBatch implements Database.Batchable < SObject > {
    GLOBAL Database.queryLocator start(Database.BatchableContext ctx) {
        String lsStatus = 'ICReady';
        string query = 'SELECT id,Name from Lead WHERE status=:lsStatus'  ;
        RETURN database.getQueryLocator(query);
    }
    GLOBAL VOID execute(Database.BatchableContext BC, List < Lead > scope) {
        Set<ID> leadIDs= new Set<ID>();
        for(Lead l: scope){
            leadIDs.add(l.id);
        }
        system.debug('LeadIDs===>'+LeadIDs);
        Set<ID> campaignIDs = new Set<ID>();
        for(CampaignMember cm : [SELECT CampaignID, LeadID, Status FROM CampaignMember WHERE LeadID IN : leadIDs]){
            campaignIDs.add(cm.CampaignID);
        }
        list<Campaign> listCampaign = new list<Campaign>();
        for(Campaign c : [select Id, Status from Campaign where Id IN : campaignIDs ]){
            c.Status = 'IC Daily Campaign Ready';
            listCampaign.add(c);
        }

        if(listCampaign.size() > 0){
            update listCampaign;
        }
    }

    GLOBAL VOID finish(Database.BatchableContext BC) {

    }
}

Test Class:

@isTest
public class Update_IC_CampaignBatch_Test {
    static testMethod void runBatch() {

        Campaign newCmp = NEW Campaign();
        newCmp.Name ='TestName';
        newCmp.Accommodation__c = 'test';
        newCmp.IsActive = True;
        insert newCmp;
        Campaign cmp = [SELECT Id, Name FROM Campaign WHERE Name = 'TestName' LIMIT 1 ];

        Lead L1 = new Lead();
        L1.lastname = 'Last';
        L1.firstname = 'First';
        L1.company = 'Company ABC';
        L1.leadsource = 'Matching Campaign';
        L1.IC_Campaign_Eligible__c = TRUE;
        L1.Status='ICReady';
        insert L1;
        Lead testLead= [SELECT Id, Name FROM Lead WHERE Name = 'First Last' LIMIT 1];

        List<CampaignMember> testCampMemb1 = new List<CampaignMember>();
        testCampMemb1.add(new CampaignMember(LeadId = testLead.Id , CampaignId = cmp.Id, Status = 'Eligible Planned Send'));
        system.debug('\n SGTEST testCampMemb1===>'+testCampMemb1);

        if (!testCampMemb1.isEmpty()) {
            Test.startTest();            
              Database.executeBatch(new Update_IC_CampaignBatch(), 1);            
            Test.stopTest();
        }
    }
}
  • 1
    Coverage stopping at execute() is a good indicator that the query in start() is not matching anything. Can you include some relevant code elements here? – David Reed Nov 28 '18 at 18:43
  • 2
    Is your test class using seeAllData=true? – Pranay Jaiswal Nov 28 '18 at 18:44
  • 1
    I think you are going to have to include some relevant code or this question is not answerable. – Adrian Larson Nov 28 '18 at 18:48
  • No - SeeAllData is not used – SeanGorman Nov 28 '18 at 18:52
  • 2
    The first thing that comes to my mind is the potential for a workflow rule + field update, or a Process Builder, or a trigger on Lead or CampaignMember that is altering your test lead's status. At this point, I think your best option is to perform a diff between your full & prod orgs to find the difference in metadata (and there must be some difference). If you don't have up-to-date local copies of your org metadata or aren't using source control, sforgcompare.herokuapp.com can help you with this. – Derek F Nov 28 '18 at 19:05
3

You forgot to insert testCampMemb1; before you started the batch, so it didn't exist in the database. You also have some questionable code that you could remove (if (!testCampMemb1.isEmpty()) { and if(listCampaign.size() > 0){, for example).

  • Hi Fox - yes that is exactly why the 3 lines don't test - hence why I thought it was a quick win. – SeanGorman Nov 28 '18 at 19:15
  • What is specifically questionable about those lines? Are you saying they are not required? – SeanGorman Nov 28 '18 at 19:37
  • 2
    @SeanGorman (a) the unit test if statement is logically impossible. This would give a seasoned programmer pause to consider why this code exists. You would do well to avoid writing logically impossible if statements when possible. (b) the execute method if statement is an unnecessary guard, and has been for years now. It simply clutters up code without any benefit. An empty list DML uses no extra CPU time or governor limits as opposed to checking the list yourself (meaning, the if statement actually wastes time). – sfdcfox Nov 28 '18 at 19:58
  • I just want to highlight for others - though this is the fix that I was trying to apply, it doesn't answer the question. Despite this, Fox, you are a scholar and a gentleman as always. – SeanGorman Nov 29 '18 at 16:43

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.