SlideShare a Scribd company logo
1 of 56
Download to read offline
Cleveland Salesforce Developer Group
All about those Tests
#CLESFDevs
Agenda
● Welcome/Intro
● Today’s Topics:
○ Closing the Test Automation Gap: A Guide to Increasing Your Velocity
■ Michael Dailey
○ The Return of H.O.T. in Cleveland
■ Lynda Kane
● Announcements & Upcoming Local Events
Lynda Kane
Co-Leader @labboopanda
Orlando Briceño Gómez
Co-Leader @orlybg
Closing the Test Automation Gap: A Guide to
Increasing Your Velocity
Closing the Test Automation Gap: A
Guide to Increasing Your Velocity
Michael Dailey
@ProvarTesting
Over to Michael…
Provar Winners!
The Return of H.O.T. in Cleveland
Lynda Kane
@labboopanda
Announcements & Upcoming Events
● World Tour NYC
○ Thursday, December 8 Salesforce+ 9:00 a.m.–5:00 p.m. ET
○ https://www.salesforce.com/world-tour/nyc/home/
● Automation Dreamin'
○ November 10th & 11th, 2022 - Virtual
○ https://sites.google.com/automationdreamin.com
● Representation Matters
○ Thursday, December 8th 2022 1:30PM - 4:30PM PST
○ https://representationmatterssummit202.splashthat.com/
● CactusForce
○ https://www.cactusforce.com/
○ THURSDAY, JANUARY 19 - FRIDAY, JANUARY 20, 2023
Cleveland
#SalesforceSaturday
Next 3 Saturday mornings
9am at Common Grounds
(Lorain & Rocky River Rds)
Posted to the Collaboration
Group, LinkedIn, & Twitter.
Sign up at Eventbrite:
https://www.eventbrite.com/cc/clevela
nd-salesforcesaturday-1087399
Join our Community Group in
Trailhead! (Cleveland
#Salesforce Saturday)
The Return of
H.O.T. in
Cleveland
The Return of
H.O.T. in
Cleveland
No, I mean Happy Over Test
classes not Betty White
Topic Introduction
Lynda’s “Safe Harbor” Statement
The topic presented in today’s presentation on Apex testing tends to be boring and
dry at best. In an effort to draw your attention and provide some comic relief
liberties have been taken. The portrayal and ideas presented here are my own
and in no way a reflection on Salesforce, the Trailblazer Community, the
Salesforce Ohaha, this Trailblazer Community group, or Developers in General. If
you are offended by or feel some of this presentation is blasphemous to your
religious beliefs, I apologize as I mean no disrespect. I only hope to provide some
entertainment while drawing your attention to and assisting you in better
understanding and being comfortable with this important topic.
The 75% Commandment
Thou shalt not
deploy to production
unless
code coverage is
75%!!!!!
Faced with this Commandment...
We struggle, we worry, we freak out.
How do we do this?
We search out and “borrow” code to get the functionality
we need but those examples almost never include test
class. We create our own code and test classes. We
ponder and stress over creating unit tests to get coverage
for every line.
And then...
API Version 24.0
Like a new Pharaoh in Egypt, starting with
API v24.0 we could no longer access all
the data in our orgs by default when
creating test classes.
So now we’re not only worried and
sweating, we’re feeling shackled and
oppressed not unlike the slaves in the
oppressively HOT Egyptian desert...
We need an oasis.
We need a plan.
We need a savior.
Like the Egyptian slaves, we need a
spokesperson.
We need...
Betty
(Older than Moses)
White
Unfortunately she wasn’t available so...
You get me.
● 13+ Years Salesforce
Experience
● 11X Certified
● 1800+ Trailhead Badges
But don’t worry I brought
2 tablets...
I. Thou shall keep code
current.
II. Thou shall use
original test data.
III. Thou shall honor the
Governor Limits.
IV. Thou shall include all
inputs.
V. Thou shall bulkify.
VI. Thou shall test multiple
contexts.
VII. Thou shall perform
simulations.
VIII. Thou shall confirm
expectations &
exceptions.
IX. Thou shall order results.
X. Thou shall comment.
… and tools
We need to take advantage of software development
methodologies like TDD (Test-Driven Development), BDD
(Behavior Driven Development), MBT (Model Based Testing),
etc. so that we grow into better developers who focus not on
75% coverage but on making sure we’re doing the right
things in our code and testing those thoroughly.
Lynda’s Golden Rule
Focus not on covering every
line but on testing the expected
functionality.
Think and create tests that:
● Portray initial data as the
code will receive it
● Assert the code affects that
data as expected
Test as you expect
the code to treat
your data.
Back to our tale
We have arrived at the
promised land, the land of Milk
& Honey (or maybe Milk &
Cookies when we’re good
developers), a land filled with
successful deployments, high
(even higher than 75%) code
coverage, proven tests and
happy Salesforce Admins and
Users. Hallelujah!
Testing Best Practices & Resources
Thou shall keep code current.
Salesforce Recommends: No more than 3 API Versions in code
Lynda Recommends: Use the most recent API Versions you are able to (& limit
the # of Versions)
As of June 2023, API 30.0 and earlier will be retired.
Test code using API Version 23.0 & earlier had access to all data by default
(SeeAllData = true has no effect here). Test code with version 24.0 and later does
not. If a test class with version 24.0 or later uses code with version 23.0 or earlier,
you still can’t access all data by default
Sometimes APEX commands are retired and newer API’s have great new features
for controlling security concerns.
Thou shall use original test data.
Salesforce Recommends: Create the necessary data in test classes, so the tests
do not have to rely on data in a particular organization. Create all test data before
calling the Test.startTest method. Since tests don't commit, you don't have to
delete any data.
Lynda Recommends: Create test data that mimics the behavior of your users
How:
● Create in each test method
● Use @TestSetup to create test data for a class and its methods
● Use a TestFactory class to generate test data and call it in @TestSetup and/or
individual test methods
● Store Test Data in a .CSV file in Static Resources, Use List<sObject> ls
= Test.loadData(Account.sObjectType, 'myResource');
Thou shall honor the Governor Limits.
Lynda Recommends: Use Test.startTest() and Test.stopTest()
Notes:
● Does not reset the context but provides an additional context
● While in this context, Governor Limits are separate
● Can only use Once (1) per Test Method!
● After stopTest(), return to original context and usage against original Governor
Limit levels continues.
● With startTest(), asynchronous calls are collected; At stopTest(), all
asynchronous processes are executed
Thou shall include all inputs.
Salesforce Recommends: If code uses conditional logic (including ternary
operators), execute each branch. Make calls to methods using both valid and
invalid inputs.
Lynda Recommends: Plan ahead and outline all the possible input data (strive
for at least 85% of anticipated situations)
Thou shall bulkify.
Salesforce Recommends: Exercise bulk trigger functionality—use at least 20
records in your tests.
Lynda Recommends:
● Tests with multiple records.
● Remember: IDs may not be in order
● Assert more than 1 resulting record.
Thou shall test with multiple contexts.
Salesforce Recommends: Use the runAs method to test your application in
different user contexts.
Lynda Recommends:
● Make sure user profiles/permissions can’t change data when they shouldn’t.
● Remember: System Administrators have Modify All Data.
● Keep in mind the Sharing Settings
Thou shall perform simulations.
Lynda Recommends: Use Mocks and Stubs where they make sense
● REST/SOAP Calls to External Systems
● REST/SOAP Calls coming to Salesforce
● Other external data usage
● Web site responses
● Simulating email sends
Note: This is an advanced developer topic!
Learn more:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm
Thou shall confirm expectations & exceptions.
Salesforce Recommends: Use the Assert class to prove that code behaves
properly. Complete successfully without throwing any exceptions, unless those
errors are expected and caught in a try…catch block. Always handle all exceptions
that are caught, instead of merely catching the exceptions.
Lynda Recommends:
● Strive for a minimum of 2 Asserts per Test Method.
● Assert if you import data (from a Static Resource) or generate bulk data
before you run that data through tests.
● If you use try...catch, be sure to create methods that raise the exceptions.
● If you used System.Assert, learn about the new Assert class.
Learn more:
https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_Assert.htm#
apex_class_System_Assert
Thou shall order results.
Salesforce Recommends: Not assume that record IDs are in sequential order.
Record IDs are not created in ascending order unless you insert multiple records
with the same request. For example, if you create an account A, and receive the
ID 001D000000IEEmT, then create account B, the ID of account B may, or may
not be sequentially higher.
Lynda Recommends:
● User ORDER BY in your SOQL when retrieving data post-test, especially if
you are using LIMIT
● ORDER BY known fields not IDs.
Thou shall comment.
Salesforce Recommends: Write comments stating not only what is supposed to
be tested, but the assumptions the tester made about the data, the expected
outcome, and so on.
Lynda Recommends:
● Help your future self, other developers and your admin!
● Include a documentation box after the first line (class declaration)
● Include who created & when, what methods are included with short
description, date/who/what for updates.
● For classes, identify the primary test class in the documentation box.
● For test classes, provide what you’re trying to test.
● Comment assumptions where used in the code.
Documentation Box Example: Apex Class
public class UserUtility {
/* Utilities for use with User object
* Created 6/30/2019 Lynda Kane
*
* Methods:
* getAllSubordinateIds - takes set of User.ID's and returns Set of UserID's for all
subordinate User.Manager
* getAllManagerIds - takes set of UserID's and returns Set of of UserID's for all managers
User.Manager
*
* Update Log:
*
* Test Class: see UserUtilityTest
*/
public static Set<ID> getAllSubordinateIds(Set<ID> EmpIds) {
// To get all sub employees (User.Manager field)
Set<ID> currentEmpIds = new Set<ID>();
...
Documentation Box Example: Apex Test Class
@isTest
public class UserUtilityTest {
/* Test Class for Utilities for use with User object
* Created 6/30/2019 Lynda Kane
*
* Methods:
* testSubordinatesGet - creates 1 manager and 2 user they manage, tests getAllSubordinateIds
(Happy Path)
* testManagersGet - creates 3 users in a 3-level hierarchy, tests getAllManagersIds (Happy
Path)
*
* Update Log:
*
*/
static testMethod void testSubordinatesGet() {
Running Unit Tests
Lynda Recommends: Run your tests often (while developing and in a preview
sandbox for each quarterly release once in production)
How:
● Salesforce User Interface (Setup - Apex Classes or Apex Text Execution)
● Developer Console
● Force.com IDE (Eclipse) - note Eclipse is no longer supported
● SFDX via the Salesforce CLI
● SOAP API
○ RunTestsResult[] runTests(RunTestsRequest ri)
Learn Moar About Testing
Apex Developers Guide:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex
_testing.htm
Trailhead Modules on Testing:
https://trailhead.salesforce.com/en/content/learn/modules/apex_testing
https://trailhead.salesforce.com/en/content/learn/modules/unit-testing-on-the-lightn
ing-platform
About Software Development Methodologies:
https://www.browserstack.com/guide/tdd-vs-bdd-vs-atdd
Test Class
Writing
Practice
Test Class Writing Practice
For each Apex Class Presented, our goals are to:
● Add a documentation box and comments
● Create a test class that tests the functionality
● Hopefully achieve >= 75% code coverage (but
functionality is our focus)
● Utilize best practices
Example 1
public class OlderAccountsUtility {
public static void updateOlderAccounts() {
// Get the 5 oldest accounts
Account[] oldAccounts = [SELECT Id, Description FROM Account ORDER
BY CreatedDate ASC LIMIT 5];
// loop through them and update the Description field
for (Account acct : oldAccounts) {
acct.Description = 'Heritage Account';
}
// save the change you made
update oldAccounts;
}
}
Source: https://trailhead.salesforce.com/content/learn/projects/quickstart-apex
Example 1: Our Modified Class
public class OlderAccountsUtility {
/*Created lbk 7/13/2019
*
* updateOlderAccount - updates description for 5 oldest accounts
*
* update log:
* 7/13/2019 lbk Changed to use Legacy_Status__c field instead
*
* test class: see OlderAccountsUtilityTest
*
* */
public static void updateOlderAccounts() {
// Get the 5 oldest accounts
Account[] oldAccounts = [SELECT Id, Legacy_Status__c FROM Account ORDER BY CreatedDate ASC LIMIT 5];
// loop through them and update the Description field
for (Account acct : oldAccounts) {
acct.Legacy_Status__c = 'Heritage';
}
// save the change you made
update oldAccounts;
}
}
Example 1: Our Test Class
@isTest
public class OlderAccountsUtilityTest {
/*Created by lbk 7/13/2019
*
* testSetupAccounts - create 10 account records
* testUpdateAccounts - runs the test and checks the changed and unchanged records
*
* update log:
*
*/
@testSetup static void testSetupAccounts() {
List<Account> createAccounts = new List<Account>();
for (Integer i = 0; i < 10; i++) {
Account a = new Account();
a.name = 'Test Account ' + i;
createAccounts.add(a);
}
insert createAccounts;
}
Example 1: Our Test Class cont.
@isTest static void testUpdateAccounts() {
List<Account> updateAccounts = [SELECT Id, Legacy_Status__c, Name FROM Account];
Assert.areEqual(10, updateAccounts.size());
Test.startTest();
OlderAccountsUtility.updateOlderAccounts();
Test.stopTest();
List<Account> check1 = [SELECT Id FROM Account WHERE Legacy_Status__c = 'Heritage'];
List<Account> check2 = [SELECT Id FROM Account WHERE Legacy_Status__c = 'New'];
Assert.areEqual(5, check1.size());
Assert.areEqual(5, check2.size());
}
}
Example 2
public with sharing class AccountHandler {
public static void CreateNewOpportunity(List<Account> accts) {
for (Account a : accts) {
Opportunity opp = new Opportunity();
opp.Name = a.Name + ' Opportunity';
opp.AccountId = a.Id;
opp.StageName = 'Prospecting';
opp.CloseDate = System.Today().addMonths(1);
insert opp;
}
}
}
Source: https://trailhead.salesforce.com/content/learn/modules/apex_basics_dotnet/execution_context
Example 2: Our Modified Class
public with sharing class AccountHandler {
/*Created lbk 7/13/2019
*
* CreateNewOpportunity: for a list of accounts, add an opportunity with
a Close Date 1 month out
*
* update log:
*
* test class: see AccountHandlerTest
*/
public static void CreateNewOpportunity(List<Account> accts) {
...
Example 2: Our Test Class
@isTest
public class AccountHandlerTest {
/* created lbk 7/13/2019
*
* update log:
*
* testNewAccountCreate - checks that new Opps created with new Accounts
*/
@isTest static void testNewAccountCreate() {
List<Account> createAccounts = new List<Account>();
for (Integer i = 0; i < 7; i++) {
Account a = new Account();
a.Name = 'Test Account ' + i;
createAccounts.add(a);
}
Example 2: Our Test Class cont.
insert createAccounts;
List<Account> runAccounts = [SELECT Id, Name FROM Account];
Assert.areEqual(7, runAccounts.size());
Test.startTest();
AccountHandler.CreateNewOpportunity(runAccounts);
Test.stopTest();
List<Opportunity> findOpps = [SELECT ID, Name, StageName, CloseDate FROM Opportunity ORDER BY Name];
system.assertEquals(7, findOpps.size());
Assert.areEqual('Prospecting', findOpps[2].StageName);
Assert.areEqual(System.Today().addMonths(1), findOpps[4].CloseDate);
}
}
Example 3
trigger ClosedOppTrigger on Opportunity (after insert,after update) {
List<task> carry=New List<task>();
for(opportunity opp:trigger.new){
if(opp.stagename=='Closed Won'){
task t=new task(whatid=opp.id,Status = 'Active',Subject = 'Follow Up
Test Task',ActivityDate = system.today() );
carry.add(t);
}
}
insert carry;
}
Source: https://developer.salesforce.com/forums/?id=906F00000005FGhIAM
Example 3: Our Modified Trigger
trigger ClosedOppTrigger on Opportunity (after insert,after update) {
/* created 7/13/2019 lbk
*
* add task to won opportunity to do followup
*
* update log:
*
* tests class: ClosedOppTriggerTest
*/
List<task> carry=New List<task>();
...
Example 3: Our Test Class
@isTest
public class ClosedOppTriggerTest {
/* created lbk 7/13/2019
*
* testSetupOpps - create 10 opps for testing
* testWonOpps - move 3 opps to Closed won and make sure Tasks were created
*
* update log:
*
*/
@testSetup static void testSetupOpps() {
Example 3: Our Test Class
@testSetup static void testSetupOpps() {
Account a = new Account(Name = 'Test Account');
insert a;
List<Opportunity> createOpps = new List<Opportunity>();
for (Integer i = 0; i < 10; i++) {
Opportunity opp = new Opportunity();
opp.Name = a.Name + ' ' + i;
opp.AccountId = a.Id;
opp.CloseDate = System.TODAY() + 90;
opp.StageName = 'Prospecting';
createOpps.add(opp);
}
insert createOpps;
}
Example 3: Our Test Class
@isTest static void testWonOpps() {
List<Opportunity> updateOpps = [SELECT Id, Name, StageName FROM Opportunity ORDER BY Name LIMIT 3];
System.Debug(updateOpps);
Test.startTest();
for (Opportunity o : updateOpps) {
o.StageName = 'Closed Won';
}
update updateOpps;
Test.stopTest();
List<Task> getTasks = [SELECT Id, Subject, ActivityDate, Status, WhatId FROM Task ORDER BY WhatID];
updateOpps.sort();
Assert.areEqual(3, getTasks.size());
Assert.areEqual(updateOpps[2].Id, getTasks[2].WhatId);
Assert.areEqual('Active',getTasks[1].Status);
}
}
CLEDevs All about Tests

More Related Content

Similar to CLEDevs All about Tests

Search Solutions 2015: Towards a new model of search relevance testing
Search Solutions 2015:  Towards a new model of search relevance testingSearch Solutions 2015:  Towards a new model of search relevance testing
Search Solutions 2015: Towards a new model of search relevance testingCharlie Hull
 
Continuous Delivery & Testing Madrid AfterTest
Continuous Delivery & Testing Madrid AfterTestContinuous Delivery & Testing Madrid AfterTest
Continuous Delivery & Testing Madrid AfterTestPeter Marshall
 
WEBINAR: Proven Patterns for Loading Test Data for Managed Package Testing
WEBINAR: Proven Patterns for Loading Test Data for Managed Package TestingWEBINAR: Proven Patterns for Loading Test Data for Managed Package Testing
WEBINAR: Proven Patterns for Loading Test Data for Managed Package TestingCodeScience
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql ServerDavid P. Moore
 
Specification-by-Example: A Cucumber Implementation
Specification-by-Example: A Cucumber ImplementationSpecification-by-Example: A Cucumber Implementation
Specification-by-Example: A Cucumber ImplementationTechWell
 
#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange
#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange
#FunLearnSeason2 - Talk 2 : Publishing your App on AppexchangeSikha Baid ☁
 
Demise of test scripts rise of test ideas
Demise of test scripts rise of test ideasDemise of test scripts rise of test ideas
Demise of test scripts rise of test ideasRichard Robinson
 
Using MLOps to Bring ML to Production/The Promise of MLOps
Using MLOps to Bring ML to Production/The Promise of MLOpsUsing MLOps to Bring ML to Production/The Promise of MLOps
Using MLOps to Bring ML to Production/The Promise of MLOpsWeaveworks
 
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austin
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austinDev ops ci-ap-is-oh-my_security-gone-agile_ut-austin
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austinMatt Tesauro
 
Get ready for your platform developer i certification webinar
Get ready for your platform developer i certification   webinarGet ready for your platform developer i certification   webinar
Get ready for your platform developer i certification webinarJackGuo20
 
Test team dynamics, Антон Мужайло
Test team dynamics, Антон МужайлоTest team dynamics, Антон Мужайло
Test team dynamics, Антон МужайлоSigma Software
 
Best Practices for Team Development in a Single Org
Best Practices for Team Development in a Single OrgBest Practices for Team Development in a Single Org
Best Practices for Team Development in a Single OrgSalesforce Developers
 
How to run an Enterprise PHP Shop
How to run an Enterprise PHP ShopHow to run an Enterprise PHP Shop
How to run an Enterprise PHP ShopJim Plush
 
The 6k startup - How to Launch a Startup on a Budget
The 6k startup - How to Launch a Startup on a BudgetThe 6k startup - How to Launch a Startup on a Budget
The 6k startup - How to Launch a Startup on a BudgetCrystal Taggart
 
Test Driven Development and Automation
Test Driven Development and AutomationTest Driven Development and Automation
Test Driven Development and AutomationMahesh Salaria
 
Barcelona Admin Group - Study Group-9nov2019
Barcelona Admin Group - Study Group-9nov2019Barcelona Admin Group - Study Group-9nov2019
Barcelona Admin Group - Study Group-9nov2019animuscrm
 

Similar to CLEDevs All about Tests (20)

Search Solutions 2015: Towards a new model of search relevance testing
Search Solutions 2015:  Towards a new model of search relevance testingSearch Solutions 2015:  Towards a new model of search relevance testing
Search Solutions 2015: Towards a new model of search relevance testing
 
Continuous Delivery & Testing Madrid AfterTest
Continuous Delivery & Testing Madrid AfterTestContinuous Delivery & Testing Madrid AfterTest
Continuous Delivery & Testing Madrid AfterTest
 
WEBINAR: Proven Patterns for Loading Test Data for Managed Package Testing
WEBINAR: Proven Patterns for Loading Test Data for Managed Package TestingWEBINAR: Proven Patterns for Loading Test Data for Managed Package Testing
WEBINAR: Proven Patterns for Loading Test Data for Managed Package Testing
 
Keeping up with PHP
Keeping up with PHPKeeping up with PHP
Keeping up with PHP
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
 
Agile testing
Agile testingAgile testing
Agile testing
 
Specification-by-Example: A Cucumber Implementation
Specification-by-Example: A Cucumber ImplementationSpecification-by-Example: A Cucumber Implementation
Specification-by-Example: A Cucumber Implementation
 
#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange
#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange
#FunLearnSeason2 - Talk 2 : Publishing your App on Appexchange
 
Demise of test scripts rise of test ideas
Demise of test scripts rise of test ideasDemise of test scripts rise of test ideas
Demise of test scripts rise of test ideas
 
Using MLOps to Bring ML to Production/The Promise of MLOps
Using MLOps to Bring ML to Production/The Promise of MLOpsUsing MLOps to Bring ML to Production/The Promise of MLOps
Using MLOps to Bring ML to Production/The Promise of MLOps
 
QA and scrum
QA and scrumQA and scrum
QA and scrum
 
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austin
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austinDev ops ci-ap-is-oh-my_security-gone-agile_ut-austin
Dev ops ci-ap-is-oh-my_security-gone-agile_ut-austin
 
Get ready for your platform developer i certification webinar
Get ready for your platform developer i certification   webinarGet ready for your platform developer i certification   webinar
Get ready for your platform developer i certification webinar
 
Test team dynamics, Антон Мужайло
Test team dynamics, Антон МужайлоTest team dynamics, Антон Мужайло
Test team dynamics, Антон Мужайло
 
Best Practices for Team Development in a Single Org
Best Practices for Team Development in a Single OrgBest Practices for Team Development in a Single Org
Best Practices for Team Development in a Single Org
 
How to run an Enterprise PHP Shop
How to run an Enterprise PHP ShopHow to run an Enterprise PHP Shop
How to run an Enterprise PHP Shop
 
FLossEd-BK Tequila Framework3.2.1
FLossEd-BK Tequila Framework3.2.1FLossEd-BK Tequila Framework3.2.1
FLossEd-BK Tequila Framework3.2.1
 
The 6k startup - How to Launch a Startup on a Budget
The 6k startup - How to Launch a Startup on a BudgetThe 6k startup - How to Launch a Startup on a Budget
The 6k startup - How to Launch a Startup on a Budget
 
Test Driven Development and Automation
Test Driven Development and AutomationTest Driven Development and Automation
Test Driven Development and Automation
 
Barcelona Admin Group - Study Group-9nov2019
Barcelona Admin Group - Study Group-9nov2019Barcelona Admin Group - Study Group-9nov2019
Barcelona Admin Group - Study Group-9nov2019
 

More from Lynda Kane

Cleveland Developers: CLI in the C-L-E slide deck
Cleveland Developers: CLI in the C-L-E slide deckCleveland Developers: CLI in the C-L-E slide deck
Cleveland Developers: CLI in the C-L-E slide deckLynda Kane
 
Migrate to Flow
Migrate to FlowMigrate to Flow
Migrate to FlowLynda Kane
 
Rock, Paper, Scissors Game with Apex Maps
Rock, Paper, Scissors Game with Apex MapsRock, Paper, Scissors Game with Apex Maps
Rock, Paper, Scissors Game with Apex MapsLynda Kane
 
Can Orlando dance the Mambo?
Can Orlando dance the Mambo?Can Orlando dance the Mambo?
Can Orlando dance the Mambo?Lynda Kane
 
Cleveland Salesforce Developers 8/13/2022
Cleveland Salesforce Developers 8/13/2022Cleveland Salesforce Developers 8/13/2022
Cleveland Salesforce Developers 8/13/2022Lynda Kane
 
Salesforce Character Cards.pdf
Salesforce Character Cards.pdfSalesforce Character Cards.pdf
Salesforce Character Cards.pdfLynda Kane
 
2022 WITness Success #Craftforce.pdf
2022 WITness Success #Craftforce.pdf2022 WITness Success #Craftforce.pdf
2022 WITness Success #Craftforce.pdfLynda Kane
 
CLE TrailheaDX 2020 Global Gathering
CLE TrailheaDX 2020 Global GatheringCLE TrailheaDX 2020 Global Gathering
CLE TrailheaDX 2020 Global GatheringLynda Kane
 

More from Lynda Kane (8)

Cleveland Developers: CLI in the C-L-E slide deck
Cleveland Developers: CLI in the C-L-E slide deckCleveland Developers: CLI in the C-L-E slide deck
Cleveland Developers: CLI in the C-L-E slide deck
 
Migrate to Flow
Migrate to FlowMigrate to Flow
Migrate to Flow
 
Rock, Paper, Scissors Game with Apex Maps
Rock, Paper, Scissors Game with Apex MapsRock, Paper, Scissors Game with Apex Maps
Rock, Paper, Scissors Game with Apex Maps
 
Can Orlando dance the Mambo?
Can Orlando dance the Mambo?Can Orlando dance the Mambo?
Can Orlando dance the Mambo?
 
Cleveland Salesforce Developers 8/13/2022
Cleveland Salesforce Developers 8/13/2022Cleveland Salesforce Developers 8/13/2022
Cleveland Salesforce Developers 8/13/2022
 
Salesforce Character Cards.pdf
Salesforce Character Cards.pdfSalesforce Character Cards.pdf
Salesforce Character Cards.pdf
 
2022 WITness Success #Craftforce.pdf
2022 WITness Success #Craftforce.pdf2022 WITness Success #Craftforce.pdf
2022 WITness Success #Craftforce.pdf
 
CLE TrailheaDX 2020 Global Gathering
CLE TrailheaDX 2020 Global GatheringCLE TrailheaDX 2020 Global Gathering
CLE TrailheaDX 2020 Global Gathering
 

Recently uploaded

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 

Recently uploaded (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 

CLEDevs All about Tests

  • 1. Cleveland Salesforce Developer Group All about those Tests #CLESFDevs
  • 2. Agenda ● Welcome/Intro ● Today’s Topics: ○ Closing the Test Automation Gap: A Guide to Increasing Your Velocity ■ Michael Dailey ○ The Return of H.O.T. in Cleveland ■ Lynda Kane ● Announcements & Upcoming Local Events
  • 3. Lynda Kane Co-Leader @labboopanda Orlando Briceño Gómez Co-Leader @orlybg
  • 4. Closing the Test Automation Gap: A Guide to Increasing Your Velocity
  • 5. Closing the Test Automation Gap: A Guide to Increasing Your Velocity Michael Dailey @ProvarTesting
  • 8. The Return of H.O.T. in Cleveland
  • 10. Announcements & Upcoming Events ● World Tour NYC ○ Thursday, December 8 Salesforce+ 9:00 a.m.–5:00 p.m. ET ○ https://www.salesforce.com/world-tour/nyc/home/ ● Automation Dreamin' ○ November 10th & 11th, 2022 - Virtual ○ https://sites.google.com/automationdreamin.com ● Representation Matters ○ Thursday, December 8th 2022 1:30PM - 4:30PM PST ○ https://representationmatterssummit202.splashthat.com/ ● CactusForce ○ https://www.cactusforce.com/ ○ THURSDAY, JANUARY 19 - FRIDAY, JANUARY 20, 2023 Cleveland #SalesforceSaturday Next 3 Saturday mornings 9am at Common Grounds (Lorain & Rocky River Rds) Posted to the Collaboration Group, LinkedIn, & Twitter. Sign up at Eventbrite: https://www.eventbrite.com/cc/clevela nd-salesforcesaturday-1087399 Join our Community Group in Trailhead! (Cleveland #Salesforce Saturday)
  • 11.
  • 12. The Return of H.O.T. in Cleveland
  • 13. The Return of H.O.T. in Cleveland No, I mean Happy Over Test classes not Betty White
  • 15. Lynda’s “Safe Harbor” Statement The topic presented in today’s presentation on Apex testing tends to be boring and dry at best. In an effort to draw your attention and provide some comic relief liberties have been taken. The portrayal and ideas presented here are my own and in no way a reflection on Salesforce, the Trailblazer Community, the Salesforce Ohaha, this Trailblazer Community group, or Developers in General. If you are offended by or feel some of this presentation is blasphemous to your religious beliefs, I apologize as I mean no disrespect. I only hope to provide some entertainment while drawing your attention to and assisting you in better understanding and being comfortable with this important topic.
  • 16. The 75% Commandment Thou shalt not deploy to production unless code coverage is 75%!!!!!
  • 17. Faced with this Commandment... We struggle, we worry, we freak out. How do we do this? We search out and “borrow” code to get the functionality we need but those examples almost never include test class. We create our own code and test classes. We ponder and stress over creating unit tests to get coverage for every line. And then...
  • 18. API Version 24.0 Like a new Pharaoh in Egypt, starting with API v24.0 we could no longer access all the data in our orgs by default when creating test classes. So now we’re not only worried and sweating, we’re feeling shackled and oppressed not unlike the slaves in the oppressively HOT Egyptian desert...
  • 19. We need an oasis. We need a plan. We need a savior. Like the Egyptian slaves, we need a spokesperson. We need...
  • 21. Unfortunately she wasn’t available so... You get me. ● 13+ Years Salesforce Experience ● 11X Certified ● 1800+ Trailhead Badges But don’t worry I brought 2 tablets...
  • 22. I. Thou shall keep code current. II. Thou shall use original test data. III. Thou shall honor the Governor Limits. IV. Thou shall include all inputs. V. Thou shall bulkify. VI. Thou shall test multiple contexts. VII. Thou shall perform simulations. VIII. Thou shall confirm expectations & exceptions. IX. Thou shall order results. X. Thou shall comment.
  • 23. … and tools We need to take advantage of software development methodologies like TDD (Test-Driven Development), BDD (Behavior Driven Development), MBT (Model Based Testing), etc. so that we grow into better developers who focus not on 75% coverage but on making sure we’re doing the right things in our code and testing those thoroughly.
  • 24. Lynda’s Golden Rule Focus not on covering every line but on testing the expected functionality. Think and create tests that: ● Portray initial data as the code will receive it ● Assert the code affects that data as expected Test as you expect the code to treat your data.
  • 25. Back to our tale We have arrived at the promised land, the land of Milk & Honey (or maybe Milk & Cookies when we’re good developers), a land filled with successful deployments, high (even higher than 75%) code coverage, proven tests and happy Salesforce Admins and Users. Hallelujah!
  • 26. Testing Best Practices & Resources
  • 27. Thou shall keep code current. Salesforce Recommends: No more than 3 API Versions in code Lynda Recommends: Use the most recent API Versions you are able to (& limit the # of Versions) As of June 2023, API 30.0 and earlier will be retired. Test code using API Version 23.0 & earlier had access to all data by default (SeeAllData = true has no effect here). Test code with version 24.0 and later does not. If a test class with version 24.0 or later uses code with version 23.0 or earlier, you still can’t access all data by default Sometimes APEX commands are retired and newer API’s have great new features for controlling security concerns.
  • 28. Thou shall use original test data. Salesforce Recommends: Create the necessary data in test classes, so the tests do not have to rely on data in a particular organization. Create all test data before calling the Test.startTest method. Since tests don't commit, you don't have to delete any data. Lynda Recommends: Create test data that mimics the behavior of your users How: ● Create in each test method ● Use @TestSetup to create test data for a class and its methods ● Use a TestFactory class to generate test data and call it in @TestSetup and/or individual test methods ● Store Test Data in a .CSV file in Static Resources, Use List<sObject> ls = Test.loadData(Account.sObjectType, 'myResource');
  • 29. Thou shall honor the Governor Limits. Lynda Recommends: Use Test.startTest() and Test.stopTest() Notes: ● Does not reset the context but provides an additional context ● While in this context, Governor Limits are separate ● Can only use Once (1) per Test Method! ● After stopTest(), return to original context and usage against original Governor Limit levels continues. ● With startTest(), asynchronous calls are collected; At stopTest(), all asynchronous processes are executed
  • 30. Thou shall include all inputs. Salesforce Recommends: If code uses conditional logic (including ternary operators), execute each branch. Make calls to methods using both valid and invalid inputs. Lynda Recommends: Plan ahead and outline all the possible input data (strive for at least 85% of anticipated situations)
  • 31. Thou shall bulkify. Salesforce Recommends: Exercise bulk trigger functionality—use at least 20 records in your tests. Lynda Recommends: ● Tests with multiple records. ● Remember: IDs may not be in order ● Assert more than 1 resulting record.
  • 32. Thou shall test with multiple contexts. Salesforce Recommends: Use the runAs method to test your application in different user contexts. Lynda Recommends: ● Make sure user profiles/permissions can’t change data when they shouldn’t. ● Remember: System Administrators have Modify All Data. ● Keep in mind the Sharing Settings
  • 33. Thou shall perform simulations. Lynda Recommends: Use Mocks and Stubs where they make sense ● REST/SOAP Calls to External Systems ● REST/SOAP Calls coming to Salesforce ● Other external data usage ● Web site responses ● Simulating email sends Note: This is an advanced developer topic! Learn more: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm
  • 34. Thou shall confirm expectations & exceptions. Salesforce Recommends: Use the Assert class to prove that code behaves properly. Complete successfully without throwing any exceptions, unless those errors are expected and caught in a try…catch block. Always handle all exceptions that are caught, instead of merely catching the exceptions. Lynda Recommends: ● Strive for a minimum of 2 Asserts per Test Method. ● Assert if you import data (from a Static Resource) or generate bulk data before you run that data through tests. ● If you use try...catch, be sure to create methods that raise the exceptions. ● If you used System.Assert, learn about the new Assert class. Learn more: https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_Assert.htm# apex_class_System_Assert
  • 35. Thou shall order results. Salesforce Recommends: Not assume that record IDs are in sequential order. Record IDs are not created in ascending order unless you insert multiple records with the same request. For example, if you create an account A, and receive the ID 001D000000IEEmT, then create account B, the ID of account B may, or may not be sequentially higher. Lynda Recommends: ● User ORDER BY in your SOQL when retrieving data post-test, especially if you are using LIMIT ● ORDER BY known fields not IDs.
  • 36. Thou shall comment. Salesforce Recommends: Write comments stating not only what is supposed to be tested, but the assumptions the tester made about the data, the expected outcome, and so on. Lynda Recommends: ● Help your future self, other developers and your admin! ● Include a documentation box after the first line (class declaration) ● Include who created & when, what methods are included with short description, date/who/what for updates. ● For classes, identify the primary test class in the documentation box. ● For test classes, provide what you’re trying to test. ● Comment assumptions where used in the code.
  • 37. Documentation Box Example: Apex Class public class UserUtility { /* Utilities for use with User object * Created 6/30/2019 Lynda Kane * * Methods: * getAllSubordinateIds - takes set of User.ID's and returns Set of UserID's for all subordinate User.Manager * getAllManagerIds - takes set of UserID's and returns Set of of UserID's for all managers User.Manager * * Update Log: * * Test Class: see UserUtilityTest */ public static Set<ID> getAllSubordinateIds(Set<ID> EmpIds) { // To get all sub employees (User.Manager field) Set<ID> currentEmpIds = new Set<ID>(); ...
  • 38. Documentation Box Example: Apex Test Class @isTest public class UserUtilityTest { /* Test Class for Utilities for use with User object * Created 6/30/2019 Lynda Kane * * Methods: * testSubordinatesGet - creates 1 manager and 2 user they manage, tests getAllSubordinateIds (Happy Path) * testManagersGet - creates 3 users in a 3-level hierarchy, tests getAllManagersIds (Happy Path) * * Update Log: * */ static testMethod void testSubordinatesGet() {
  • 39. Running Unit Tests Lynda Recommends: Run your tests often (while developing and in a preview sandbox for each quarterly release once in production) How: ● Salesforce User Interface (Setup - Apex Classes or Apex Text Execution) ● Developer Console ● Force.com IDE (Eclipse) - note Eclipse is no longer supported ● SFDX via the Salesforce CLI ● SOAP API ○ RunTestsResult[] runTests(RunTestsRequest ri)
  • 40. Learn Moar About Testing Apex Developers Guide: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex _testing.htm Trailhead Modules on Testing: https://trailhead.salesforce.com/en/content/learn/modules/apex_testing https://trailhead.salesforce.com/en/content/learn/modules/unit-testing-on-the-lightn ing-platform About Software Development Methodologies: https://www.browserstack.com/guide/tdd-vs-bdd-vs-atdd
  • 42. Test Class Writing Practice For each Apex Class Presented, our goals are to: ● Add a documentation box and comments ● Create a test class that tests the functionality ● Hopefully achieve >= 75% code coverage (but functionality is our focus) ● Utilize best practices
  • 43. Example 1 public class OlderAccountsUtility { public static void updateOlderAccounts() { // Get the 5 oldest accounts Account[] oldAccounts = [SELECT Id, Description FROM Account ORDER BY CreatedDate ASC LIMIT 5]; // loop through them and update the Description field for (Account acct : oldAccounts) { acct.Description = 'Heritage Account'; } // save the change you made update oldAccounts; } } Source: https://trailhead.salesforce.com/content/learn/projects/quickstart-apex
  • 44. Example 1: Our Modified Class public class OlderAccountsUtility { /*Created lbk 7/13/2019 * * updateOlderAccount - updates description for 5 oldest accounts * * update log: * 7/13/2019 lbk Changed to use Legacy_Status__c field instead * * test class: see OlderAccountsUtilityTest * * */ public static void updateOlderAccounts() { // Get the 5 oldest accounts Account[] oldAccounts = [SELECT Id, Legacy_Status__c FROM Account ORDER BY CreatedDate ASC LIMIT 5]; // loop through them and update the Description field for (Account acct : oldAccounts) { acct.Legacy_Status__c = 'Heritage'; } // save the change you made update oldAccounts; } }
  • 45. Example 1: Our Test Class @isTest public class OlderAccountsUtilityTest { /*Created by lbk 7/13/2019 * * testSetupAccounts - create 10 account records * testUpdateAccounts - runs the test and checks the changed and unchanged records * * update log: * */ @testSetup static void testSetupAccounts() { List<Account> createAccounts = new List<Account>(); for (Integer i = 0; i < 10; i++) { Account a = new Account(); a.name = 'Test Account ' + i; createAccounts.add(a); } insert createAccounts; }
  • 46. Example 1: Our Test Class cont. @isTest static void testUpdateAccounts() { List<Account> updateAccounts = [SELECT Id, Legacy_Status__c, Name FROM Account]; Assert.areEqual(10, updateAccounts.size()); Test.startTest(); OlderAccountsUtility.updateOlderAccounts(); Test.stopTest(); List<Account> check1 = [SELECT Id FROM Account WHERE Legacy_Status__c = 'Heritage']; List<Account> check2 = [SELECT Id FROM Account WHERE Legacy_Status__c = 'New']; Assert.areEqual(5, check1.size()); Assert.areEqual(5, check2.size()); } }
  • 47. Example 2 public with sharing class AccountHandler { public static void CreateNewOpportunity(List<Account> accts) { for (Account a : accts) { Opportunity opp = new Opportunity(); opp.Name = a.Name + ' Opportunity'; opp.AccountId = a.Id; opp.StageName = 'Prospecting'; opp.CloseDate = System.Today().addMonths(1); insert opp; } } } Source: https://trailhead.salesforce.com/content/learn/modules/apex_basics_dotnet/execution_context
  • 48. Example 2: Our Modified Class public with sharing class AccountHandler { /*Created lbk 7/13/2019 * * CreateNewOpportunity: for a list of accounts, add an opportunity with a Close Date 1 month out * * update log: * * test class: see AccountHandlerTest */ public static void CreateNewOpportunity(List<Account> accts) { ...
  • 49. Example 2: Our Test Class @isTest public class AccountHandlerTest { /* created lbk 7/13/2019 * * update log: * * testNewAccountCreate - checks that new Opps created with new Accounts */ @isTest static void testNewAccountCreate() { List<Account> createAccounts = new List<Account>(); for (Integer i = 0; i < 7; i++) { Account a = new Account(); a.Name = 'Test Account ' + i; createAccounts.add(a); }
  • 50. Example 2: Our Test Class cont. insert createAccounts; List<Account> runAccounts = [SELECT Id, Name FROM Account]; Assert.areEqual(7, runAccounts.size()); Test.startTest(); AccountHandler.CreateNewOpportunity(runAccounts); Test.stopTest(); List<Opportunity> findOpps = [SELECT ID, Name, StageName, CloseDate FROM Opportunity ORDER BY Name]; system.assertEquals(7, findOpps.size()); Assert.areEqual('Prospecting', findOpps[2].StageName); Assert.areEqual(System.Today().addMonths(1), findOpps[4].CloseDate); } }
  • 51. Example 3 trigger ClosedOppTrigger on Opportunity (after insert,after update) { List<task> carry=New List<task>(); for(opportunity opp:trigger.new){ if(opp.stagename=='Closed Won'){ task t=new task(whatid=opp.id,Status = 'Active',Subject = 'Follow Up Test Task',ActivityDate = system.today() ); carry.add(t); } } insert carry; } Source: https://developer.salesforce.com/forums/?id=906F00000005FGhIAM
  • 52. Example 3: Our Modified Trigger trigger ClosedOppTrigger on Opportunity (after insert,after update) { /* created 7/13/2019 lbk * * add task to won opportunity to do followup * * update log: * * tests class: ClosedOppTriggerTest */ List<task> carry=New List<task>(); ...
  • 53. Example 3: Our Test Class @isTest public class ClosedOppTriggerTest { /* created lbk 7/13/2019 * * testSetupOpps - create 10 opps for testing * testWonOpps - move 3 opps to Closed won and make sure Tasks were created * * update log: * */ @testSetup static void testSetupOpps() {
  • 54. Example 3: Our Test Class @testSetup static void testSetupOpps() { Account a = new Account(Name = 'Test Account'); insert a; List<Opportunity> createOpps = new List<Opportunity>(); for (Integer i = 0; i < 10; i++) { Opportunity opp = new Opportunity(); opp.Name = a.Name + ' ' + i; opp.AccountId = a.Id; opp.CloseDate = System.TODAY() + 90; opp.StageName = 'Prospecting'; createOpps.add(opp); } insert createOpps; }
  • 55. Example 3: Our Test Class @isTest static void testWonOpps() { List<Opportunity> updateOpps = [SELECT Id, Name, StageName FROM Opportunity ORDER BY Name LIMIT 3]; System.Debug(updateOpps); Test.startTest(); for (Opportunity o : updateOpps) { o.StageName = 'Closed Won'; } update updateOpps; Test.stopTest(); List<Task> getTasks = [SELECT Id, Subject, ActivityDate, Status, WhatId FROM Task ORDER BY WhatID]; updateOpps.sort(); Assert.areEqual(3, getTasks.size()); Assert.areEqual(updateOpps[2].Id, getTasks[2].WhatId); Assert.areEqual('Active',getTasks[1].Status); } }