Hello Trailblazers,
In this post we're going to learn How to create test class for a flow? Most of the developers I've met have never written a test class for flow and some of them are not even aware that we can write a test class for flow and evaluate the test coverage. The question that I get is: Is it possible to create test class for a flow??
YES, THIS IS POSSIBLE!! LET'S SEE HOW?
Create a Flow
First of all, let's create a simple flow. I am sharing the details of the flow below:
Flow Type: Record Triggered Flow
Object: Lead
Trigger the Flow When: A record is created or updated
Entry Conditions: All Conditions Are Met (AND) -> AnnualRevenue -> Is Changed -> True
Optimize the Flow for: Fast Field Updates
Flow Label: Update Lead Rating based on Annual Revenue
Flow Description: This flow will update lead rating based on the value of annual revenue
What this flow is going to do?
Our flow will update the Lead Rating based on the value of Annual Revenue of lead. There are 3 conditions that it'll cover:
- Annual Revenue is less than 25,000 -> Lead Rating = Cold
- Annual Revenue is between 25,000 and 75,000 -> Lead Rating = Warm
- Annual Revenue is greater than 75,000 -> Lead Rating = Hot
Now that we have our update elements, we need to link these 3 update elements with our decision outcomes so that, when:
- Annual Revenue is less than 25,000 -> Lead Rating = Cold
- Annual Revenue is between 25,000 and 75,000 -> Lead Rating = Warm
- Annual Revenue is greater than 75,000 -> Lead Rating = Hot
Create a test class for the above flow
/* * Created:- 07/05/2022 * Last Updated:- 07/05/2022 * Description:- This is the test class for Update_Lead_Rating_based_on_Annual_Revenue Flow */ @isTest public with sharing class LeadUpdateFlowTest { // * Constants static final Integer NUMBER_OF_RECORDS = 200; static final String RATING_COLD = 'Cold'; static final String RATING_WARM = 'Warm'; static final String RATING_HOT = 'Hot'; // * Description: This method is used to create initial data for the test methods @TestSetup static void makeData() { List<Lead> leads = new List<Lead>(); for(Integer i=1; i<=NUMBER_OF_RECORDS; i++) { leads.add(new Lead(LastName = 'Test Lead ' + i, Company='Test Company')); } insert leads; } /* * Description: This method is used to verify lead rating * when the annual revenue is less than 25,000 */ @isTest public static void updateLeadBasedOnAnnualRevenueLessThan25kTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 24999; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_COLD, lead.Rating, 'Lead rating should be: ' + RATING_COLD); } Test.stopTest(); } /* * Description: This method is used to verify lead rating * when the annual revenue is between 25,000 and 75,000. * We're keeping the value at floor i.e. 25,000 for this test */ @isTest public static void updateLeadBasedOnAnnualRevenueBetween25kAnd75kFloorTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 25000; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } Test.stopTest(); } /* * Description: This method is used to verify lead rating * when the annual revenue is between 25,000 and 75,000. * We're keeping the value at ceiling i.e. 75,000 for this test */ @isTest public static void updateLeadBasedOnAnnualRevenueBetween25kAnd75kCeilingTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 75000; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } Test.stopTest(); } /* * Description: This method is used to verify lead rating * when the annual revenue is greater than 75,000 */ @isTest public static void updateLeadBasedOnAnnualRevenueGreaterThan75kTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 75001; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_HOT, lead.Rating, 'Lead rating should be: ' + RATING_HOT); } Test.stopTest(); } /* * Description: This method is used to cover all low elements and verify lead rating * when the annual revenue is less than 25k, between 25k and 75k and also greater than 75k */ @isTest public static void updateLeadBasedOnAnnualRevenueAllElementsTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 20000; } update leads; List<Lead> updatedLeadsWithRatingCold = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingCold) { System.assertEquals(RATING_COLD, lead.Rating, 'Lead rating should be: ' + RATING_COLD); } for(Lead lead : leads) { lead.AnnualRevenue = 50000; } update leads; List<Lead> updatedLeadsWithRatingWarm = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingWarm) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } for(Lead lead : leads) { lead.AnnualRevenue = 80000; } update leads; List<Lead> updatedLeadsWithRatingHot = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingHot) { System.assertEquals(RATING_HOT, lead.Rating, 'Lead rating should be: ' + RATING_HOT); } Test.stopTest(); } }
// * Constants static final Integer NUMBER_OF_RECORDS = 200; static final String RATING_COLD = 'Cold'; static final String RATING_WARM = 'Warm'; static final String RATING_HOT = 'Hot';
// * Description: This method is used to create initial data for the test methods @TestSetup static void makeData() { List<Lead> leads = new List<Lead>(); for(Integer i=1; i<=NUMBER_OF_RECORDS; i++) { leads.add(new Lead(LastName = 'Test Lead ' + i, Company='Test Company')); } insert leads; }
/* * Description: This method is used to verify lead rating * when the annual revenue is less than 25,000 */ @isTest public static void updateLeadBasedOnAnnualRevenueLessThan25kTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 24999; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_COLD, lead.Rating, 'Lead rating should be: ' + RATING_COLD); } Test.stopTest(); }
sfdx force:data:soql:query --query "SELECT Id, ApexTestClassId, TestMethodName, FlowVersionId, NumElementsCovered, NumElementsNotCovered FROM FlowTestCoverage WHERE FlowVersion.Definition.DeveloperName = 'Update_Lead_Rating_based_on_Annual_Revenue' AND TestMethodName = 'updateLeadBasedOnAnnualRevenueLessThan25kTest'" --usetoolingapi
/* * Description: This method is used to verify lead rating * when the annual revenue is between 25,000 and 75,000. * We're keeping the value at floor i.e. 25,000 for this test */ @isTest public static void updateLeadBasedOnAnnualRevenueBetween25kAnd75kFloorTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 25000; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } Test.stopTest(); }
/* * Description: This method is used to verify lead rating * when the annual revenue is between 25,000 and 75,000. * We're keeping the value at ceiling i.e. 75,000 for this test */ @isTest public static void updateLeadBasedOnAnnualRevenueBetween25kAnd75kCeilingTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 75000; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } Test.stopTest(); }
sfdx force:data:soql:query --query "SELECT Id, ApexTestClassId, TestMethodName, FlowVersionId, NumElementsCovered, NumElementsNotCovered FROM FlowTestCoverage WHERE FlowVersion.Definition.DeveloperName = 'Update_Lead_Rating_based_on_Annual_Revenue' AND (TestMethodName = 'updateLeadBasedOnAnnualRevenueBetween25kAnd75kFloorTest' OR TestMethodName = 'updateLeadBasedOnAnnualRevenueBetween25kAnd75kCeilingTest')" --usetoolingapi
/* * Description: This method is used to verify lead rating * when the annual revenue is greater than 75,000 */ @isTest public static void updateLeadBasedOnAnnualRevenueGreaterThan75kTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 75001; } update leads; List<Lead> updatedLeads = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeads) { System.assertEquals(RATING_HOT, lead.Rating, 'Lead rating should be: ' + RATING_HOT); } Test.stopTest(); }
sfdx force:data:soql:query --query "SELECT Id, ApexTestClassId, TestMethodName, FlowVersionId, NumElementsCovered, NumElementsNotCovered FROM FlowTestCoverage WHERE FlowVersion.Definition.DeveloperName = 'Update_Lead_Rating_based_on_Annual_Revenue' AND TestMethodName = 'updateLeadBasedOnAnnualRevenueGreaterThan75kTest'" --usetoolingapi
/* * Description: This method is used to cover all low elements and verify lead rating * when the annual revenue is less than 25k, between 25k and 75k and also greater than 75k */ @isTest public static void updateLeadBasedOnAnnualRevenueAllElementsTest() { List<Lead> leads = [SELECT AnnualRevenue FROM Lead]; Test.startTest(); for(Lead lead : leads) { lead.AnnualRevenue = 20000; } update leads; List<Lead> updatedLeadsWithRatingCold = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingCold) { System.assertEquals(RATING_COLD, lead.Rating, 'Lead rating should be: ' + RATING_COLD); } for(Lead lead : leads) { lead.AnnualRevenue = 50000; } update leads; List<Lead> updatedLeadsWithRatingWarm = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingWarm) { System.assertEquals(RATING_WARM, lead.Rating, 'Lead rating should be: ' + RATING_WARM); } for(Lead lead : leads) { lead.AnnualRevenue = 80000; } update leads; List<Lead> updatedLeadsWithRatingHot = [SELECT Rating FROM Lead]; for(Lead lead : updatedLeadsWithRatingHot) { System.assertEquals(RATING_HOT, lead.Rating, 'Lead rating should be: ' + RATING_HOT); } Test.stopTest(); }
sfdx force:data:soql:query --query "SELECT Id, ApexTestClassId, TestMethodName, FlowVersionId, NumElementsCovered, NumElementsNotCovered FROM FlowTestCoverage WHERE FlowVersion.Definition.DeveloperName = 'Update_Lead_Rating_based_on_Annual_Revenue' AND TestMethodName = 'updateLeadBasedOnAnnualRevenueAllElementsTest'" --usetoolingapi
sfdx force:data:soql:query --query "SELECT Id, ApexTestClassId, TestMethodName, FlowVersionId, NumElementsCovered, NumElementsNotCovered FROM FlowTestCoverage WHERE FlowVersion.Definition.DeveloperName = 'Update_Lead_Rating_based_on_Annual_Revenue'" --usetoolingapi
Great article
ReplyDeleteThank you for sharing this article, i didn't know you can create an apex test class for Flow
ReplyDelete