You need to sign in to do that
Don't have an account?
Trigger Coverage Fails on Deployment - HELP...SALES PROCESSES STALLED
I don't know what happened, but I had several triggers working previously, and now I can't even deploy previous triggers that used to be working in production. The first trigger and class is below.. I think there is something wrong with my test class that is not making the trigger fire (test coverage is 100% in sandbox). Perhaps this causing the code coverage upon deployment to be 0%.... PLEASE HELP.
THIS IS MY TRIGGER THAT WORKS IN SANDBOX
trigger statusChangeAutoEmail on Lead (after update) {
List<Messaging.SingleEmailMessage> messages = new List<Messaging.SingleEmailMessage>();
List<Lead> leadsToUpdate=new List<Lead>();
List<Lead> leadList= [select Id, Email,X1st_Attempt_Email__c,X2nd_Attempt_Email__c,
Closed_Lost_Email__c, Status,Franchise_Concept__c, Owner.Name,Owner.Email from Lead
where International__c=false AND No_Auto_Email__c=false AND EmailBouncedReason=NULL AND
(Status!='New Lead' or Status!='Qualified')];
for(Lead leadEmail : leadList) {
if(leadEmail.Status == '1st Attempt' && leadEmail.X1st_Attempt_Email__c==false
) {
//send Email
String template = ''; // initialize variable to hold template name filled in below
template = 'Standard Auto Sales Appt Reminder Email';
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setTemplateId([select id from EmailTemplate where Name = :template].id);
message.setTargetObjectId(leadEmail.id);
// String to hold the email addresses to which the email is being sent.
message.setToAddresses (new String[] {leadEmail.Email});
message.setsaveAsActivity(true);
message.setsenderDisplayName(leadEmail.Owner.Name);
message.setreplyTo(leadEmail.Owner.Email);
// Add the e-mail to the list to be sent
messages.add(message);
//update to Lead so email only sent once
leadEmail.X1st_Attempt_Email__c=true;
leadsToUpdate.add(leadEmail);
}
else if(leadEmail.Status == '2nd Attempt' && leadEmail.X2nd_Attempt_Email__c==false
) {
//send Email
String template = ''; // initialize variable to hold template name filled in below
template = 'Standard Auto Sales Appt Reminder Email';
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setTemplateId([select id from EmailTemplate where Name = :template].id);
message.setTargetObjectId(leadEmail.id);
// String to hold the email addresses to which the email is being sent.
message.setToAddresses (new String[] {leadEmail.Email});
message.setsaveAsActivity(true);
message.setsenderDisplayName(leadEmail.Owner.Name);
message.setreplyTo(leadEmail.Owner.Email);
// Add the e-mail to the list to be sent
messages.add(message);
//update to Lead so email only sent once
leadEmail.X2nd_Attempt_Email__c=true;
leadsToUpdate.add(leadEmail);
}
else if(leadEmail.Status == 'Closed - Lost' && leadEmail.Closed_Lost_Email__c==false
) {
//send Email
String template = ''; // initialize variable to hold template name filled in below
template = 'Standard Auto Sales Appt Reminder Email';
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setTemplateId([select id from EmailTemplate where Name = :template].id);
message.setTargetObjectId(leadEmail.id);
// String to hold the email addresses to which the email is being sent.
message.setToAddresses (new String[] {leadEmail.Email});
message.setsaveAsActivity(true);
message.setsenderDisplayName(leadEmail.Owner.Name);
message.setreplyTo(leadEmail.Owner.Email);
// Add the e-mail to the list to be sent
messages.add(message);
//update to Lead so email only sent once
leadEmail.Closed_Lost_Email__c=true;
leadsToUpdate.add(leadEmail);
}
else{
}
} //end for statement
Messaging.sendEmail(messages);
update leadsToUpdate;
} //end trigger
THIS IS MY TEST CLASS
@isTest
private class statusChangeAutoEmail {
static testMethod void statusChangeAutoEmail() {
List<Messaging.SingleEmailMessage> messages = new List<Messaging.SingleEmailMessage>();
List<Lead> leadsToUpdate=new List<Lead>();
Lead[] leadsToCreate=new Lead[]{};
for(Integer x=0; x<20; x++){
Lead ld = new Lead(lastname='test', Status='1st Attempt', email='test@testing.com',company='test');
leadsToCreate.add(ld);
}
for(Integer x=0; x<20; x++){
Lead ld = new Lead(lastname='test', Status='2nd Attempt', email='test@testing.com',company='test');
leadsToCreate.add(ld);
}
for(Integer x=0; x<20; x++){
Lead ld = new Lead(lastname='test', Status='Closed - Lost', email='test@testing.com',company='test',
Closed_Lost_Dispositions__c='Other');
leadsToCreate.add(ld);
}
//Now for the test...
Test.startTest();
insert leadsToCreate;
Messaging.sendEmail(messages);
Test.stopTest();
}
}
I'm pretty frantic at this point, since our sales team relies on several of these triggers that used to work... Help would be MOST APPRECIATED
-Amanda
instead of using lists use Map and sets automatically the trigger handles bulk data and also one more option is to go for asynchronous class using a future method,
All Answers
Your trigger is only running on update and in your test you are only inserting the leads.
Oh my goodness!! Is that all that's wrong? So, if I insert the test leads then update them in the testing section, you think that will solve the problem? Also, I'm wondering if my trigger is "bulkified". Any thoughts?
Thank you so much! I have been up all night trying to get everything reverted back. I'll mark this as solved after I try the changes.
instead of using lists use Map and sets automatically the trigger handles bulk data and also one more option is to go for asynchronous class using a future method,
I can see a couple of possible issues in your trigger.
1. You might be causing an infinite loop because you are updating leads in a lead update trigger. Your query doesn't seem to be filtering to exclude leads where you updated the attempt_email fields so the trigger might run on those leads over and over.
2. You are querying the template id inside your for loop so if you process more than 20 leads at a time you'll hit the governor limit for soql queries in a trigger.
You are unbelievably quick and it couldn't be any more appreciated right now. I have one ear on the phone with salesforce support, while trying to make these changes. I changed my test class to update the lead list, and I still cannot deploy.
I'm sorry I'm such an amateur, but could you please give me a starting point on how to modify my trigger to include sets and maps? I want to do everything correctly this time so this doesn't happen again, since I think I deployed faulty classes/triggers previously. Aaahh!!
Thank you for your reply! I'm amazed by the feedback here. I wish I had gotten on here sooner!!
I did exclude the query for template Id, as I figured that was probably an issue.
As for your first point, do you think I should include something in the where clause to say something like 'attempt_email != true'. Is that what you mean by excluding them after update?
Thanks again!!
The Apex code Developer's Guide has a pretty good introduction to writing bulk triggers. When you run your test on sandbox or try to deploy it should tell you what error prevented the trigger from running/deploying successfully.
Thanks for the link. My error message when testing ddeployment in Eclipse is that pretty much every line in the trigger is not tested even from line 2 (how is that possible)... I'm so completely lost again although I thought I was making headway.
Is this still mostly a problem with my test class not initiating the trigger?
P.S. I want to crawl in the fetal position right now and just hide under my desk until this fixes itself. :)
Can you post your new test code and the last lines of the debug log. I.E. where it either exits the testmethod or throws an exception. Also, maybe I don't understand your business logic but do you really want to send an email to every lead that matches your query when any lead is updated? Wouldn't you just want to send emails to the leads that were updated?
Okay, sorry. Now of course my computer and Eclipse are temporarily freezing. I guess they're as tired as I am :) I have the last bit of debug code from the failure (didn't know how much was needed). It doesn't seem to fail. As for the business logic, yes, I would only want to send an email to those updated, but it's my Apex logic that I can figure out.. How would I specify to send only to those updated leads?
//ERRORS FROM DEPLOYMENT (also doesn't test all the lines, especially those within the first two conditional statements-I don't know why it decides to test only the last conditional statement when status='Closed - Lost')
# Test Results:
Run Failures:
statusChangeAutoEmail.statusChangeAutoEmail System.LimitException: Apex heap size too large: 2185444
//TEST CLASS
Long day...
YES!!! This is what did the trick. I used a set to first gather all the unique ids in the trigger, then populated a list with the query on the leads whose Ids were in the set (along with my other necessary criteria).
Thank you for pointing me in the right direction!! 100% coverage with my test class and trigger coverage. Now, I'm having fun again and will work on more triggers. Thanks everyone!