*******Page
<apex:page standardController="Automated_Test_Run__c" extensions="AutomatedTestSetup_Controller" Sidebar="False" id="pg" docType="html-5.0">
<apex:form id="frm">
<apex:pageBlock title="Job Schedule - Test Execution">
<apex:pageMessages />
<apex:pageBlockSection title="Job Schedule" columns="1">
<apex:outputPanel rendered="{!hasScheduledJobs}">
Automated Test execution <a href="/08e">scheduled</a>
</apex:outputPanel>
<apex:outputPanel rendered="{!NOT(hasScheduledJobs)}">
<apex:pageBlockSectionItem >
<div>
<p>Select the Date and Time to schedule the Automated Test execution</p>
</div>
</apex:pageBlockSectionItem>
</apex:outputPanel>
<apex:pageBlockSectionItem id="ScheduleVal" rendered="{!NOT(hasScheduledJobs)}">
<apex:OutputLabel value="Date and Time"/>
<!--<apex:input type="datetime" value="{!startdate}" required="true" /> -->
<apex:InputField required="true" value="{!Automated_Test_Run__c.Schedule__c}" ID="Schdval"/>
</apex:pageBlockSectionItem>
<!-- <apex:commandButton value="Submit" action="{!scheduleJobs}"/> -->
<!--<apex:commandButton value="Submit" Action="{!scheduleJobs}">
<apex:param name="DttValue" value="{!Automated_Test_Run__c.Schedule__c}" assignTo="{!DtValue}"/>
</apex:commandButton>-->
<apex:commandLink value="Submit" rendered="{!NOT(hasScheduledJobs)}" action="{!scheduleJobs}" styleClass="btn">
<apex:param name="DtValue" value="{!Automated_Test_Run__c.Schedule__c}" assignTo="{!DtValue}"/>
</apex:commandLink>
<apex:commandLink value="Cancel" rendered="{!hasScheduledJobs}" action="{!CancelJobs}" styleClass="btn">
</apex:commandLink>
</apex:pageBlockSection>
<apex:pageBlockSection title="Statistics" id="Piechartsec" columns="2">
<div>
<p>Percentage completion of test execution:</p>
</div>
<!--<apex:commandButton value="Refresh" Action="{!getPieData}" reRender="Piechartsec2"/>
<apex:commandlink value=" refresh" status="progress" onclick="window.location.href='/apex/AutomatedTestSetupVFP" />-->
<apex:commandlink value=" Refresh " status="progress" onclick="window.location.href='/apex/AutomatedTestSetupVFP" styleClass="btn"/>
<apex:chart height="250" width="350" data="{!pieData}" id="Piechartsec2">
<apex:pieSeries dataField="data" labelField="name"/>
<apex:legend position="right"/>
</apex:chart>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
**************
public with sharing class AutomatedTestSetup_Controller {
public AutomatedTestSetup_Controller(ApexPages.StandardController controller) {
refreshHasScheduledJobs();
refreshHasTestRun();
}
public boolean hasScheduledJobs { get; set; }
public boolean hasTestRun { get; set; }
public boolean isRunning { get; set; }
public boolean isEmailing { get; set; }
public AutomatedTestSetup_Controller ATS { get; set; }
public String DtValue {get; set; }
public String Staticstics;
public void refreshHasScheduledJobs() {
integer jobCount = [select count() from CronJobDetail where Name like 'TestRunner%' and JobType = '7'];
hasScheduledJobs = jobCount == 1;
}
public void refreshHasTestRun() {
integer runCount = [select count() from Automated_Test_Run__c limit 1];
hasTestRun = runCount > 0;
}
public string getTestRunLink() {
return '/' + Automated_Test_Run__c.SObjectType.getDescribe().getKeyPrefix();
}
public AutomatedTestSetup_Controller() {
refreshHasScheduledJobs();
refreshHasTestRun();
}
public PageReference scheduleJobs() {
//String InputDtValue = ApexPages.currentPage().getParameters().get('DtValue');
// System.debug('Date & Time is given***'+InputDtValue);
System.debug('Date & Time is given***1'+DtValue);
if(DtValue!='null' && DtValue!='' ){
//DateTime Schdtime = (DateTime)Json.deserialize('"'+DtValue+'"', DateTime.class);
//DtValue Format: Sat Aug 25 17:12:00 GMT 2018
//0 12 17 25 Aug 2018 Sat
// 0 12 17 25 AUG ? 2017
// Seconds Minutes Hours Day Of Month Month Day Of Week Year
// 0 12 17 25 AUG ? 2017
String[] splited = DtValue.split(' ');
String day = splited[2];
String month = splited[1];
String HMS = splited[3];
String[] splitedHMS = HMS.split(':');
String hour = splitedHMS[0];
String minute = splitedHMS[1];
String second = splitedHMS[2];
String year =splited[5];
//String minute = string.valueOf(Schdtime.minute() + 1);
//String year = string.valueOf(Schdtime.year());
String strSchedule = '0 ' + minute + ' ' + hour + ' ' + day + ' ' + month + ' ?' + ' ' + year;
System.debug('***strSchedule***'+strSchedule);
//String DaTime=ApexPages.currentPage().getParameters().get('{$Automated_Test_Run__c.Schedule__c}');
//System.debug('Date & Time is'+one);
TestRunner.setup(strSchedule);
refreshHasScheduledJobs();
//ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Jobs scheduled'));
}
else{
ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'Please Select Date Time Value and then Select Submit Button to Schedule job');
ApexPages.addMessage(myMsg);
}
RETURN NULL;
}
public PageReference CancelJobs() {
//List<CronTrigger> jobsToAbort = [select id,Name from CronJobDetail where Name like 'TestRunner%' and JobType = '7'];
List<CronTrigger> jobsToAbort = [select Id from CronTrigger where CronJobDetail.JobType = '7' and CronJobDetail.Name like 'TestRunner%'];
for (CronTrigger job : jobsToAbort) {
System.abortJob(job.Id);
}
//PageReference pageRef = '/apex/AutomatedTestSetupVFP';
PageReference pageRef = new PageReference('/apex/AutomatedTestSetupVFP');
pageRef.setRedirect(true);
return pageRef;
}
public void createTestRun() {
User currentUser = [select Email from User where Id = :UserInfo.getUserId()];
insert new Automated_Test_Run__c(Name = 'All Tests', Emails__c = currentUser.Email);
refreshHasTestRun();
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Automated Test Run created'));
}
public void run() {
TestRunner.enqueueTests();
isRunning = true;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Tests queued'));
}
public void email() {
TestRunnerResults.emailUnprocessedJobStatus();
isEmailing = true;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Results processed and emailed'));
}
//Statistics
public List<PieWedgeData> getPieData() {
//Select id,Status from ApexTestQueueItem where ParentJobId='7070K00008HsU7EQAV'
Test_Runner_Job__c RunningJob =[Select Name,Automated_Test_Run__c,CreatedDate From Test_Runner_Job__c where Processed__c = false order by CreatedDate desc limit 1];
//integer Cmpltd = [select count() FROM ApexTestResult WHERE Outcome = 'Pass' and AsyncApexJobId=:RunningJob.Name];
integer Cmpltd = [select count() FROM ApexTestQueueItem where Status='Completed' and ParentJobId=:RunningJob.Name];
integer Queuedjobs = [select count() FROM ApexTestQueueItem where Status='Queued' and ParentJobId=:RunningJob.Name];
Integer Tot=Cmpltd+Queuedjobs;
Integer Pending=Tot-Queuedjobs;
Staticstics='Total Testclasses='+Tot+'Pending Testclasses='+Pending;
List<PieWedgeData> data = new List<PieWedgeData>();
data.add(new PieWedgeData('Completed'+' '+Cmpltd, +Cmpltd));
data.add(new PieWedgeData('In Progress'+' '+Queuedjobs, +Queuedjobs));
return data;
}
// Wrapper class
public class PieWedgeData {
public String name { get; set; }
public Integer data { get; set; }
public Integer Cmpltd{ get; set; }
public Integer Queuedjobs{ get; set; }
public PieWedgeData(String name, Integer data) {
this.name = name;
this.data = data;
}
}
}
*************
global class TestRunner implements Schedulable {
// derived from http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_unit_tests_running.htm#APISectionTitle
public static void setup(String strSchedule) {
try {
String cronexpression=strSchedule;
system.schedule('TestRunner',cronexpression, new TestRunner());
// system.schedule('TestRunnerResults', '0 30 23 ? * SUN-THU', new TestRunnerResults());
} catch (Asyncexception ex) {
system.debug('Job already scheduled');
ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'Please Select Future Date Time');
ApexPages.addMessage(myMsg);
}
}
global void execute(SchedulableContext SC) {
enqueueTests();
}
// Enqueue all unit test classes as spec'd by Automated_Test_Run__c record(s)
public static list<ID> enqueueTests() {
list<Id> jobIds = new list<Id>();
for (Automated_Test_Run__c run : [select Query__c, Excluded_Classes__c,
Email_on_Pass__c, Exclude_Managed_Packages__c
from Automated_Test_Run__c where Active__c = true]) {
string whereExcluded = '';
if (run.Excluded_Classes__c != null) {
for (string c : run.Excluded_Classes__c.split('[,\\s]+')) {
whereExcluded += 'and Name != \'' + c + '\'';
}
}
if (run.Exclude_Managed_Packages__c == True) {
whereExcluded += ' AND NameSpacePrefix = null';
}
string query = 'SELECT Id FROM ApexClass WHERE Name LIKE \'' + run.Query__c + '\' ' + whereExcluded;
ApexClass[] testClasses = Database.query(query);
if (testClasses.size() > 0) {
ApexTestQueueItem[] queueItems = new List<ApexTestQueueItem>();
for (ApexClass cls : testClasses) {
queueItems.add(new ApexTestQueueItem(ApexClassId=cls.Id));
}
if (!Test.isRunningTest()) {
insert queueItems;
// Get the job ID of the first queue item returned.
ApexTestQueueItem item =
[SELECT ParentJobId FROM ApexTestQueueItem
WHERE Id=:queueItems[0].Id LIMIT 1];
insert new Test_Runner_Job__c(Name = item.parentjobid, Automated_Test_Run__c = run.Id);
jobIds.add(item.parentjobid);
}
}
}
return jobIds;
}
public static list<Messaging.SingleEmailMessage> emailMethodStatus(list<Test_Runner_Job__c> jobs) {
set<string> jobNames = new set<string>();
for (Test_Runner_Job__c job : jobs) {
jobNames.add(job.Name);
}
ApexTestResult[] results =
[SELECT AsyncApexJobId, Outcome, ApexClass.Name, MethodName, Message, StackTrace
FROM ApexTestResult
WHERE AsyncApexJobId in :jobNames];
return emailMethodStatus(jobs, results);
}
public static list<Messaging.SingleEmailMessage> emailMethodStatus(list<Test_Runner_Job__c> jobs, ApexTestResult[] results) {
list<Messaging.SingleEmailMessage> messages = new list<Messaging.SingleEmailMessage>();
for (Test_Runner_Job__c job : jobs) {
system.debug('Test Runner Job: Id ' + job.Id + ' Name ' + job.Name);
integer passed = 0;
integer total = 0;
string failTable = '<table border="1" cellpadding="5px">';
string className = '';
for (ApexTestResult atr : results) {
system.debug('Apex Test Result: Id ' + atr.AsyncApexJobId);
if ((string)atr.AsyncApexJobId == job.Name || (Test.isRunningTest() && jobs.size() == 1)) {
if (atr.Outcome == 'Pass') {
passed++;
} else {
if (atr.ApexClass.Name != className) {
className = atr.ApexClass.Name;
failTable += '<tr style="background: #ddd; font-weight: bold;"><td colspan="2">' + className + '</td></tr>\n';
}
failTable += '<tr><td>' + atr.MethodName + '</td><td> ' + atr.message + '</td></tr>\n';
}
total++;
}
}
failTable += '</table>';
string body = '<p>' + passed + '/' + total + ' tests passed</p>\n';
boolean allPassed = passed == total;
if (!allPassed) {
body += '<p>Test Failures:</p>\n' + failTable;
}
if ((allPassed && job.Automated_Test_Run__r.Email_on_Pass__c) || !allPassed) {
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(job.Automated_Test_Run__r.Emails__c.split('[,\\s]+'));
mail.setSubject(job.Automated_Test_Run__r.Name + ' Automated Test Results: ' + (passed < total ? 'Fail' : 'Pass'));
mail.setHtmlBody(body);
System.debug(mail);
messages.add(mail);
}
}
if (!Test.isRunningTest()) {
Messaging.sendEmail(messages);
}
return messages;
}
}
*******************
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog
https://developer.salesforce.com/forums/?id=9060G000000XhvVQAS
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_datetime.htm
DateTime myDateTime = DateTime.newInstance(1997, 1, 31, 7, 8, 16);
DateTime newDateTime = myDateTime.addHours(3);
DateTime expected = DateTime.newInstance(1997, 1, 31, 10, 8, 16);
System.assertEquals(expected, newDateTime);
********
<apex:page standardController="Automated_Test_Run__c" extensions="AutomatedTestSetup_Controller" Sidebar="False" id="pg" docType="html-5.0">
<apex:form id="frm">
<apex:pageBlock title="Job Schedule - Test Execution">
<apex:pageMessages />
<apex:pageBlockSection title="Job Schedule" columns="1">
<apex:outputPanel rendered="{!hasScheduledJobs}">
Automated Test execution <a href="/08e">scheduled</a>
</apex:outputPanel>
<apex:outputPanel rendered="{!NOT(hasScheduledJobs)}">
<apex:pageBlockSectionItem >
<div>
<p>Select the Date and Time to schedule the Automated Test execution</p>
</div>
</apex:pageBlockSectionItem>
</apex:outputPanel>
<apex:pageBlockSectionItem id="ScheduleVal" rendered="{!NOT(hasScheduledJobs)}">
<apex:OutputLabel value="Date and Time"/>
<!--<apex:input type="datetime" value="{!startdate}" required="true" /> -->
<apex:InputField required="true" value="{!Automated_Test_Run__c.Schedule__c}" ID="Schdval"/>
</apex:pageBlockSectionItem>
<!-- <apex:commandButton value="Submit" action="{!scheduleJobs}"/> -->
<!--<apex:commandButton value="Submit" Action="{!scheduleJobs}">
<apex:param name="DttValue" value="{!Automated_Test_Run__c.Schedule__c}" assignTo="{!DtValue}"/>
</apex:commandButton>-->
<apex:commandLink value="Submit" rendered="{!NOT(hasScheduledJobs)}" action="{!scheduleJobs}" styleClass="btn">
<apex:param name="DtValue" value="{!Automated_Test_Run__c.Schedule__c}" assignTo="{!DtValue}"/>
</apex:commandLink>
<apex:commandLink value="Cancel" rendered="{!hasScheduledJobs}" action="{!CancelJobs}" styleClass="btn">
</apex:commandLink>
</apex:pageBlockSection>
<apex:pageBlockSection title="Statistics" id="Piechartsec" columns="2">
<div>
<p>Percentage completion of test execution:</p>
</div>
<!--<apex:commandButton value="Refresh" Action="{!getPieData}" reRender="Piechartsec2"/>
<apex:commandlink value=" refresh" status="progress" onclick="window.location.href='/apex/AutomatedTestSetupVFP" />-->
<apex:commandlink value=" Refresh " status="progress" onclick="window.location.href='/apex/AutomatedTestSetupVFP" styleClass="btn"/>
<apex:chart height="250" width="350" data="{!pieData}" id="Piechartsec2">
<apex:pieSeries dataField="data" labelField="name"/>
<apex:legend position="right"/>
</apex:chart>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
**************
public with sharing class AutomatedTestSetup_Controller {
public AutomatedTestSetup_Controller(ApexPages.StandardController controller) {
refreshHasScheduledJobs();
refreshHasTestRun();
}
public boolean hasScheduledJobs { get; set; }
public boolean hasTestRun { get; set; }
public boolean isRunning { get; set; }
public boolean isEmailing { get; set; }
public AutomatedTestSetup_Controller ATS { get; set; }
public String DtValue {get; set; }
public String Staticstics;
public void refreshHasScheduledJobs() {
integer jobCount = [select count() from CronJobDetail where Name like 'TestRunner%' and JobType = '7'];
hasScheduledJobs = jobCount == 1;
}
public void refreshHasTestRun() {
integer runCount = [select count() from Automated_Test_Run__c limit 1];
hasTestRun = runCount > 0;
}
public string getTestRunLink() {
return '/' + Automated_Test_Run__c.SObjectType.getDescribe().getKeyPrefix();
}
public AutomatedTestSetup_Controller() {
refreshHasScheduledJobs();
refreshHasTestRun();
}
public PageReference scheduleJobs() {
//String InputDtValue = ApexPages.currentPage().getParameters().get('DtValue');
// System.debug('Date & Time is given***'+InputDtValue);
System.debug('Date & Time is given***1'+DtValue);
if(DtValue!='null' && DtValue!='' ){
//DateTime Schdtime = (DateTime)Json.deserialize('"'+DtValue+'"', DateTime.class);
//DtValue Format: Sat Aug 25 17:12:00 GMT 2018
//0 12 17 25 Aug 2018 Sat
// 0 12 17 25 AUG ? 2017
// Seconds Minutes Hours Day Of Month Month Day Of Week Year
// 0 12 17 25 AUG ? 2017
String[] splited = DtValue.split(' ');
String day = splited[2];
String month = splited[1];
String HMS = splited[3];
String[] splitedHMS = HMS.split(':');
String hour = splitedHMS[0];
String minute = splitedHMS[1];
String second = splitedHMS[2];
String year =splited[5];
//String minute = string.valueOf(Schdtime.minute() + 1);
//String year = string.valueOf(Schdtime.year());
String strSchedule = '0 ' + minute + ' ' + hour + ' ' + day + ' ' + month + ' ?' + ' ' + year;
System.debug('***strSchedule***'+strSchedule);
//String DaTime=ApexPages.currentPage().getParameters().get('{$Automated_Test_Run__c.Schedule__c}');
//System.debug('Date & Time is'+one);
TestRunner.setup(strSchedule);
refreshHasScheduledJobs();
//ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Jobs scheduled'));
}
else{
ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'Please Select Date Time Value and then Select Submit Button to Schedule job');
ApexPages.addMessage(myMsg);
}
RETURN NULL;
}
public PageReference CancelJobs() {
//List<CronTrigger> jobsToAbort = [select id,Name from CronJobDetail where Name like 'TestRunner%' and JobType = '7'];
List<CronTrigger> jobsToAbort = [select Id from CronTrigger where CronJobDetail.JobType = '7' and CronJobDetail.Name like 'TestRunner%'];
for (CronTrigger job : jobsToAbort) {
System.abortJob(job.Id);
}
//PageReference pageRef = '/apex/AutomatedTestSetupVFP';
PageReference pageRef = new PageReference('/apex/AutomatedTestSetupVFP');
pageRef.setRedirect(true);
return pageRef;
}
public void createTestRun() {
User currentUser = [select Email from User where Id = :UserInfo.getUserId()];
insert new Automated_Test_Run__c(Name = 'All Tests', Emails__c = currentUser.Email);
refreshHasTestRun();
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Automated Test Run created'));
}
public void run() {
TestRunner.enqueueTests();
isRunning = true;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Tests queued'));
}
public void email() {
TestRunnerResults.emailUnprocessedJobStatus();
isEmailing = true;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Results processed and emailed'));
}
//Statistics
public List<PieWedgeData> getPieData() {
//Select id,Status from ApexTestQueueItem where ParentJobId='7070K00008HsU7EQAV'
Test_Runner_Job__c RunningJob =[Select Name,Automated_Test_Run__c,CreatedDate From Test_Runner_Job__c where Processed__c = false order by CreatedDate desc limit 1];
//integer Cmpltd = [select count() FROM ApexTestResult WHERE Outcome = 'Pass' and AsyncApexJobId=:RunningJob.Name];
integer Cmpltd = [select count() FROM ApexTestQueueItem where Status='Completed' and ParentJobId=:RunningJob.Name];
integer Queuedjobs = [select count() FROM ApexTestQueueItem where Status='Queued' and ParentJobId=:RunningJob.Name];
Integer Tot=Cmpltd+Queuedjobs;
Integer Pending=Tot-Queuedjobs;
Staticstics='Total Testclasses='+Tot+'Pending Testclasses='+Pending;
List<PieWedgeData> data = new List<PieWedgeData>();
data.add(new PieWedgeData('Completed'+' '+Cmpltd, +Cmpltd));
data.add(new PieWedgeData('In Progress'+' '+Queuedjobs, +Queuedjobs));
return data;
}
// Wrapper class
public class PieWedgeData {
public String name { get; set; }
public Integer data { get; set; }
public Integer Cmpltd{ get; set; }
public Integer Queuedjobs{ get; set; }
public PieWedgeData(String name, Integer data) {
this.name = name;
this.data = data;
}
}
}
*************
global class TestRunner implements Schedulable {
// derived from http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_unit_tests_running.htm#APISectionTitle
public static void setup(String strSchedule) {
try {
String cronexpression=strSchedule;
system.schedule('TestRunner',cronexpression, new TestRunner());
// system.schedule('TestRunnerResults', '0 30 23 ? * SUN-THU', new TestRunnerResults());
} catch (Asyncexception ex) {
system.debug('Job already scheduled');
ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO,'Please Select Future Date Time');
ApexPages.addMessage(myMsg);
}
}
global void execute(SchedulableContext SC) {
enqueueTests();
}
// Enqueue all unit test classes as spec'd by Automated_Test_Run__c record(s)
public static list<ID> enqueueTests() {
list<Id> jobIds = new list<Id>();
for (Automated_Test_Run__c run : [select Query__c, Excluded_Classes__c,
Email_on_Pass__c, Exclude_Managed_Packages__c
from Automated_Test_Run__c where Active__c = true]) {
string whereExcluded = '';
if (run.Excluded_Classes__c != null) {
for (string c : run.Excluded_Classes__c.split('[,\\s]+')) {
whereExcluded += 'and Name != \'' + c + '\'';
}
}
if (run.Exclude_Managed_Packages__c == True) {
whereExcluded += ' AND NameSpacePrefix = null';
}
string query = 'SELECT Id FROM ApexClass WHERE Name LIKE \'' + run.Query__c + '\' ' + whereExcluded;
ApexClass[] testClasses = Database.query(query);
if (testClasses.size() > 0) {
ApexTestQueueItem[] queueItems = new List<ApexTestQueueItem>();
for (ApexClass cls : testClasses) {
queueItems.add(new ApexTestQueueItem(ApexClassId=cls.Id));
}
if (!Test.isRunningTest()) {
insert queueItems;
// Get the job ID of the first queue item returned.
ApexTestQueueItem item =
[SELECT ParentJobId FROM ApexTestQueueItem
WHERE Id=:queueItems[0].Id LIMIT 1];
insert new Test_Runner_Job__c(Name = item.parentjobid, Automated_Test_Run__c = run.Id);
jobIds.add(item.parentjobid);
}
}
}
return jobIds;
}
public static list<Messaging.SingleEmailMessage> emailMethodStatus(list<Test_Runner_Job__c> jobs) {
set<string> jobNames = new set<string>();
for (Test_Runner_Job__c job : jobs) {
jobNames.add(job.Name);
}
ApexTestResult[] results =
[SELECT AsyncApexJobId, Outcome, ApexClass.Name, MethodName, Message, StackTrace
FROM ApexTestResult
WHERE AsyncApexJobId in :jobNames];
return emailMethodStatus(jobs, results);
}
public static list<Messaging.SingleEmailMessage> emailMethodStatus(list<Test_Runner_Job__c> jobs, ApexTestResult[] results) {
list<Messaging.SingleEmailMessage> messages = new list<Messaging.SingleEmailMessage>();
for (Test_Runner_Job__c job : jobs) {
system.debug('Test Runner Job: Id ' + job.Id + ' Name ' + job.Name);
integer passed = 0;
integer total = 0;
string failTable = '<table border="1" cellpadding="5px">';
string className = '';
for (ApexTestResult atr : results) {
system.debug('Apex Test Result: Id ' + atr.AsyncApexJobId);
if ((string)atr.AsyncApexJobId == job.Name || (Test.isRunningTest() && jobs.size() == 1)) {
if (atr.Outcome == 'Pass') {
passed++;
} else {
if (atr.ApexClass.Name != className) {
className = atr.ApexClass.Name;
failTable += '<tr style="background: #ddd; font-weight: bold;"><td colspan="2">' + className + '</td></tr>\n';
}
failTable += '<tr><td>' + atr.MethodName + '</td><td> ' + atr.message + '</td></tr>\n';
}
total++;
}
}
failTable += '</table>';
string body = '<p>' + passed + '/' + total + ' tests passed</p>\n';
boolean allPassed = passed == total;
if (!allPassed) {
body += '<p>Test Failures:</p>\n' + failTable;
}
if ((allPassed && job.Automated_Test_Run__r.Email_on_Pass__c) || !allPassed) {
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(job.Automated_Test_Run__r.Emails__c.split('[,\\s]+'));
mail.setSubject(job.Automated_Test_Run__r.Name + ' Automated Test Results: ' + (passed < total ? 'Fail' : 'Pass'));
mail.setHtmlBody(body);
System.debug(mail);
messages.add(mail);
}
}
if (!Test.isRunningTest()) {
Messaging.sendEmail(messages);
}
return messages;
}
}
*******************
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog
https://developer.salesforce.com/forums/?id=9060G000000XhvVQAS
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_datetime.htm
DateTime myDateTime = DateTime.newInstance(1997, 1, 31, 7, 8, 16);
DateTime newDateTime = myDateTime.addHours(3);
DateTime expected = DateTime.newInstance(1997, 1, 31, 10, 8, 16);
System.assertEquals(expected, newDateTime);
********
No comments:
Post a Comment