function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Wesley HWesley H 

Code Coverage showing inconsistent values, preventing deployment

We are attempting to move a simple Apex Class and Apex Test Class from Sandbox to Production, and blocked by Code Coverage Failure error. Our Code Coverage is showing 100% in Production (via Developer Console), yet we are seeing a Code Coverage Failure Error (coverage = 33%) even on "Validate" (not "Deploy") of non-apex change set. We have followed instructions in Knowledge Article 000335222 (https://help.salesforce.com/articleView?id=000335222&type=1&mode=1) carefully to reset Code Coverage numbers and are still seeing the above error on validation of non-apex change set as well as on attempt to deploy an apex-loaded change set including test class. Apex Class and Apex Test Class code below for reference, any help greatly appreciated!
 
Public class AutoConvertLeads
{
    @InvocableMethod
    public static void LeadAssign(List<Lead> LeadIds)
    {
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        for(Lead currentlead: LeadIds){
                Account[] matchedaccount = [SELECT Id, Name FROM Account WHERE Name=:currentlead.Company LIMIT 1];
                if(matchedaccount.size() > 0) {
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead.id);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion
                Leadconvert.setAccountId(matchedaccount[0].id);
                MassLeadconvert.add(Leadconvert);
                }
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}

And Test Class:
@isTest 
      public class TestAutoConvertLeads{
      static void createnewlead(){
      User userToCreate = [SELECT id FROM user WHERE profile.name='System Administrator' Limit 1];
      
      Test.startTest();    
      Lead leadToCreate =new Lead();
      List<Lead> LeadIds= New List<Lead>();
      leadToCreate.ownerid= userToCreate.id;
      leadToCreate.LastName ='Gupta';
      leadToCreate.Company='Salesforce';
      insert leadToCreate; 
      LeadIds.add(leadToCreate);
      
      LeadStatus CLeadStatus = new LeadStatus();
      
      Account AccountToCreate = new Account();
      AccountToCreate.ownerid= userToCreate.id;
      AccountToCreate.Name = 'Salesforce';
      insert AccountToCreate; 
      
      AutoConvertLeads.LeadAssign(LeadIds);
      
      Test.stopTest();
   }
}

 
Best Answer chosen by Wesley H
Wesley HWesley H
@Abdul, Development Mode NOT checked (and wasn't before).

@Andrew, thanks, but already been down that road.

However...I found the issue: somehow my test class was missing a test method (line 3 of my test code above), so it was passing with 0/0 tests in sandbox (100%!) but bombing in the change set to Production. I fixed line 3 to read, "static testMethod void createnewlead(){" and I got 1/1 tests (also 100%) in sandbox and a flawless deployment to Production. Sorry that was so elementary, but thank you all for your help!

All Answers

Abdul KhatriAbdul Khatri
Hi Wesley

I see a potential best practise violation in the Apex  class above and have made a fix here. I have commented that code with the comment so you know where I am talking about.
public class AutoConvertLeads {

    @InvocableMethod
    public static void LeadAssign(List<Lead> LeadIds)
    {
        Set<String> companySet = new Set<String>();
        Map<String, Account> accountCompanyMap = new Map<String, Account>();
        List<Database.LeadConvert> MassLeadconvert = new List<Database.LeadConvert>();
        
        LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
        
        for(Lead currentlead : LeadIds){
            companySet.add(currentlead.Company);
        }
        
        for(Account account : [SELECT Id, Name FROM Account WHERE Name = :companySet])
        {
            accountCompanyMap.put(account.Name, account);
        }
                
        if(accountCompanyMap.isEmpty()) return;
        
        for(Lead currentlead: LeadIds)
        {
            //SOQL within for loop is a violation
            //Account[] matchedaccount = [SELECT Id, Name FROM Account WHERE Name=:currentlead.Company LIMIT 1];
            //if(matchedaccount.size() > 0)
            if(accountCompanyMap.get(currentlead.Company) != null)
            {
                Database.LeadConvert Leadconvert = new Database.LeadConvert();
                Leadconvert.setLeadId(currentlead.id);                
                Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
                Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion              
                Leadconvert.setAccountId(accountCompanyMap.get(currentlead.Company).Id);
                MassLeadconvert.add(Leadconvert);
            }
        }
        
        if (!MassLeadconvert.isEmpty()) {
            List<Database.LeadConvertResult> lcr = Database.convertLead(MassLeadconvert);
        }
    }
}

Let me if this help
Wesley HWesley H
Thanks, Abdul. Apex code worked fine in Sandbox, including with SOQL in for loop. 

Bigger picture, I'm getting the Code Coverage Failure error every time I deploy or even validate a deployment of anything from Sandbox to Production. "Anything" includes a change set with a simple custom field (no Apex in sight), which produced the coverage error. And again, we have followed instructions in Knowledge Article 000335222 (https://help.salesforce.com/articleView?id=000335222&type=1&mode=1) carefully to reset Code Coverage numbers.

How can my Production code coverage be 100% from Development Console produce 33% Code Coverage errors?
William BoyerWilliam Boyer
Do you run all tests? Maybe a test fails and it takes an all-or-nothing approach where if one test fails, they all do. I usually choose the Custom test and enter the test class name(s) that relate to the code that I want to deploy.
Abdul KhatriAbdul Khatri
Are you running all your tests in Developer Console?
Wesley HWesley H
Thanks, William, good idea. When I ran just my Test Class on deploy to Production it bombed in a different way, showing "Fatal Error," Coverage = 0%, and listing AutoConvertLeads (the class I'm moving) as the culprit. @Abdul, when I ran tests in sandbox Developer Console I see 100% coverage overall and for the specific class (see image below).

User-added image
William BoyerWilliam Boyer
Wesley,
Try having the production Developer Console open when you run the deployment. I believe it creates a log so you can see where the error is occurring so you can pinpoint the issue.
Wesley HWesley H
William, just tried again with Developer Console open, no errors logged (only a series of innocuous Browser Application "VisualForce View State" logs)...
Abdul KhatriAbdul Khatri
Can you check in Production with your user setting if developer mode is not checked. It should not be checked.

User-added image
Andrew GAndrew G
Hi 
TL:DR
Have you tried running the existing test classes in Production to have it "reset" the coverage results for all classes? 
Go to Settings > Custom Code > Apex Test Execution .  Button <Select Tests...> , click the top check box for all and hit Run.
Maybe do it out of business hours but I don't think the performance hit to end users should be that bad. 

The other thing to try, and this I would do out of hours, is to "Compile all classes" in the Apex Classes section of your Production environment.
User-added image

My loose thought process, and I recall this from many moons ago, is that sometimes the coverage details get lost or corrupted over time and the recompile and manual re-run in the production environment help to straighten things out.

HTH

Andrew
Wesley HWesley H
@Abdul, Development Mode NOT checked (and wasn't before).

@Andrew, thanks, but already been down that road.

However...I found the issue: somehow my test class was missing a test method (line 3 of my test code above), so it was passing with 0/0 tests in sandbox (100%!) but bombing in the change set to Production. I fixed line 3 to read, "static testMethod void createnewlead(){" and I got 1/1 tests (also 100%) in sandbox and a flawless deployment to Production. Sorry that was so elementary, but thank you all for your help!
This was selected as the best answer
Andrew GAndrew G
@Wesley

a-ha
sometimes we don't see the trees for the forest ...or is it the other way around.

As a side note, testMethod is deprecated, so the preference is to use the @IsTest annotation on classes and methods.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_isTest.htm

Glad you got it sorted.
Regards
Andrew
Wesley HWesley H
Thanks, Andrew. So it appears I had it right before I added testMethod (see original code above), but I was getting 0/0 before and 1/1 after...what gives?
William BoyerWilliam Boyer
Wesley,
You may have another test class that runs that code as well. Were you running all tests in your dev environment as well? After running the test(s), go to your AutoConvertLeads class, then in the top left click 'Code Coverage: None' and you can see what tests ran parts of your code and the percentage. My best guess is that more than one test class covered this code and that's what you were seeing.