Test Reports

Like all Apex code, Salesforce Reports and Dashboards API via Apex code requires test coverage.

The Reporting Apex methods don’t run in system mode, they run in the context of the current user (also called the context user or the logged-in user). The methods have access to whatever the current user has access to.

In Apex tests, report runs always ignore the SeeAllData annotation, regardless of whether the annotation is set to true or false. This means that report results will include pre-existing data that the test didn’t create. There is no way to disable the SeeAllData annotation for a report execution. To limit results, use a filter on the report.

Records inserted during the test method aren’t guaranteed to appear in the report results, even though report runs ignore the SeeAllData annotation. To limit report results reliably, use a filter, not a record count.

Note

Create a Reports Test Class

The following example tests asynchronous and synchronous reports. This sample assumes you have created and saved a report with the Developer Name Closed_Sales_This_Quarter. Each method:

  • Creates a new Opportunity object and uses it to set a filter on the report.
  • Runs the report.
  • Calls assertions to validate the data.

In Apex tests, asynchronous reports execute only after the test is stopped using the Test.stopTest method. Test.stopTest flushes asynchronous work only in the current test method. A helper method that later calls Reports.ReportManager.getReportInstance doesn’t rerun the report. Always check getStatus() before you call getReportResults(). If the status is Error, the instance finished unsuccessfully—that’s a status value, not an Apex exception.

Note

1@IsTest
2public with sharing class ReportsInApexTest{
3
4    @IsTest(SeeAllData='true')
5    public static void testAsyncReportWithTestData() {
6
7      List <Report> reportList = [SELECT Id,DeveloperName FROM Report WHERE
8          DeveloperName = 'Closed_Sales_This_Quarter' WITH USER_MODE];
9      String reportId = (String)reportList.get(0).get('Id');
10      
11      // Create an Opportunity object.
12      Opportunity opp = new Opportunity(Name='ApexTestOpp', StageName='stage',
13          Probability = 95, CloseDate=system.today());
14      insert as user opp;
15    
16      Reports.ReportMetadata reportMetadata =
17          Reports.ReportManager.describeReport(reportId).getReportMetadata();
18      
19      // Add a filter.
20      List<Reports.ReportFilter> filters = new List<Reports.ReportFilter>(); 
21      Reports.ReportFilter newFilter = new Reports.ReportFilter();
22      newFilter.setColumn('OPPORTUNITY_NAME');
23      newFilter.setOperator('equals');
24      newFilter.setValue('ApexTestOpp');
25      filters.add(newFilter);
26      reportMetadata.setReportFilters(filters);
27      
28      Test.startTest();
29       
30      Reports.ReportInstance instanceObj =
31          Reports.ReportManager.runAsyncReport(reportId,reportMetadata,false);
32      String instanceId = instanceObj.getId();
33      
34      // Report instance is not available yet.
35      Test.stopTest();
36      // After the stopTest method, the report has finished executing
37      // and the instance is available.
38     
39      instanceObj = Reports.ReportManager.getReportInstance(instanceId);
40      Assert.areEqual('Success', instanceObj.getStatus(),
41          'Async report failed: ' + instanceObj);
42      Assert.areEqual(1, reportMetadata.getReportFilters().size());
43      Assert.areEqual('OPPORTUNITY_NAME', reportMetadata.getReportFilters()[0].getColumn());
44
45      // Pass the instance ID to a helper only after stopTest.
46      MyReportService.processInstance(instanceId);
47    }
48  
49    @IsTest(SeeAllData='true')
50    public static void testSyncReportWithTestData() {
51    
52      // Create an Opportunity Object.
53      Opportunity opp = new Opportunity(Name='ApexTestOpp', StageName='stage',
54          Probability = 95, CloseDate=system.today());
55      insert as user opp;
56      
57      List <Report> reportList = [SELECT Id,DeveloperName FROM Report WHERE
58          DeveloperName = 'Closed_Sales_This_Quarter' WITH USER_MODE];
59      String reportId = (String)reportList.get(0).get('Id');
60      
61      Reports.ReportMetadata reportMetadata =
62          Reports.ReportManager.describeReport(reportId).getReportMetadata();
63      
64      // Add a filter.
65      List<Reports.ReportFilter> filters = new List<Reports.ReportFilter>(); 
66      Reports.ReportFilter newFilter = new Reports.ReportFilter();
67      newFilter.setColumn('OPPORTUNITY_NAME');
68      newFilter.setOperator('equals');
69      newFilter.setValue('ApexTestOpp');
70      filters.add(newFilter);
71      reportMetadata.setReportFilters(filters);
72      
73      Reports.ReportResults result =
74          Reports.ReportManager.runReport(reportId,reportMetadata,false);
75      Assert.isNotNull(result);
76      Assert.areEqual(1, reportMetadata.getReportFilters().size());
77      Assert.areEqual('OPPORTUNITY_NAME', reportMetadata.getReportFilters()[0].getColumn());
78    }
79}
80
81public with sharing class MyReportService {
82    public static void processInstance(String instanceId) {
83        Reports.ReportInstance inst =
84            Reports.ReportManager.getReportInstance(instanceId);
85        Assert.areEqual('Success', inst.getStatus(),
86            'Async report failed: ' + inst);
87        // Safe to call inst.getReportResults()
88    }
89}