SlideShare a Scribd company logo
10 Principles of Apex Testing
May 21st, 2015
#forcewebinar
Speakers
Kevin Poorman
Principle Architect, EDL
Consulting
@Codefriar
#forcewebinar
Safe Harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:
This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if
any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-
looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of
product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of
management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments
and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our
service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of
growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and
any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain,
and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling
non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the
financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on
Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of
the Investor Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may
not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently
available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
#forcewebinar
Go Social!
Salesforce Developers
+Salesforce Developers
Salesforce Developers
Salesforce Developers The video will be posted to
YouTube & the webinar recap
page (same URL as registration).
This webinar is being recorded!
@salesforcedevs / #forcewebinar
So make sure to
leave comments
on YouTube
#forcewebinar
▪ Don’t wait until the end to ask your question!
– Technical support will answer questions starting now.
▪ Respect Q&A etiquette
– Please don’t repeat questions. The support team is working
their way down the queue.
▪ Stick around for live Q&A at the end
– Speakers will tackle more questions at the end, time-
allowing. If no one asks questions, Kevin will.
▪ Head to Developer Forums
– More questions? Visit developer.salesforce.com/forums
Have Questions?
#forcewebinar
Agenda
1. Why we do Testing
2. 10 principles of Apex Testing
3. Questions and Answers
#forcewebinar
Why test? (when you have users)
#forcewebinar
Why we test?
 Tests provide assurance of functionality
 Tests reduce cost of change
 Tests encourage modular, reusable code
 Tests help identify engineering and architectural bugs
 Tests help document expected behavior
 Tests + Code = less likely to produce bugs
#forcewebinar
Principle #1, Use Asserts
 A test without Assert methods isn’t a test, it’s code
execution
 Three Assert methods built-in
– System.Assert(boolean-expression, ‘friendly message’)
– System.AssertEquals(expect, actual, ‘friendly message’)
– System.AssertNotEquals(expected, actual, ‘friendly message)
 Every test method should include at least one assertion
#forcewebinar
Principle #1, Use Asserts
You can write your own assert methods!
@isTest
Public class customAssertions{
public class customAssertionException extends Exception{}
Public Boolean DuplicateAccount(Account a, Account b){
// … compare accounts
if(duplicate != true) {
Throw new customAssertionException(‘whoa, it’s not the
same’);
}
return true;
}
}
#forcewebinar
Principle #2, use startTest and stopTest
 Test.startTest() and Test.stopTest() help facilitate
testing.
 startTest() resets DML, CPU Time and other governor
limits, ensuring any limits you hit come from your tested
code!
 stopTest() Forces asynchronous code to complete.
#forcewebinar
Principle #2, use startTest and stopTest
 General pattern is to
– Create your test data
– Start the test
– Use that test data within your tested method
– End the Test
– Assert your code works as expected
#forcewebinar
Principle #3, Positive Tests
 Write ‘Positive Tests’
 Positive tests test the expected behavior
 Lets talk about multiple expected behaviors
 Not just happy path testing
#forcewebinar
Principle #3, Positive Tests
Public class exampleCode {
Public Integer add(Integer one, Integer two){
return one + two;
}
}
#forcewebinar
Principle #3, Positive Tests
@isTest
private class exampleCode_Tests {
@isTest static void test_Add_Postive() {
exampleCode drWho = new exampleCode();
Test.startTest();
Integer testValue = drWho.add(5,7);
Test.stopTest();
System.assertEquals(12, testValue,
‘Expected 5+7 to equal 12’);
}
#forcewebinar
Principle #4, Negative Tests
 Negative tests prove that your code properly handles
exceptions and errors.
 The general pattern is to call your method within a
try/catch block in the test. Since you expect an
exception you’ll catch it in the catch block
 Less intuitive but more powerful!
#forcewebinar
Principle #4, Negative Tests
Public class exampleCode {
Public class exampleCodeException{}
Public Integer division(Integer one, Integer two){
if(two == 0) {
Throw new exampleCodeException(‘Dividing by zero makes kittens
cry’);
}
return one / two;
}
}
#forcewebinar
Principle #4, Negative Tests
@isTest
private class exampleCode_Tests {
@isTest static void test_Divide_Negative() {
exampleCode drWho = new exampleCode();
Boolean didCatchProperException = false;
Test.startTest();
Try {
drWho.divide(1, 0);
} catch (exampleCodeException AwesomeException){
didCatchProperException = true;
}
Test.stopTest();
System.assert(didCatchProperException,
‘Properly caught custom Exception’);
}
#forcewebinar
Principle #5, User Tests
 User based tests prove your security model
 Test with Users of different Roles / Profiles and
Permission sets!
 The pattern works like this: Create a user with a given
profile. As needed assign permission sets. Test both
positive and negative users.
#forcewebinar
Principle #5, User Tests
Public class exampleCode {
Public class exampleCodeException{}
Public Integer getBankAccount(Account a){
return a.SuperSecretBankAccountNum__c;
}
}
#forcewebinar
Principle #5, User Tests Positive
@isTest
private class exampleCode_Tests {
@isTest static void test_getBankAccount_Positive() {
exampleCode drWho = new exampleCode();
User u = AwesomeTestLib.getUserWithProfile(‘JediProfile’);
Account a = (Account)TestFactory.createSObject(new Account());
Integer result;
System.runAs(u){
Test.startTest();
result = drWho.getBankAccount(a);
Test.stopTest();
}
System.assertNotEquals(result, null,
‘Expected this user to have access to bank #’);
}
#forcewebinar
Principle #5, User Tests - Negative
@isTest
private class exampleCode_Tests {
@isTest static void test_getBankAccount_UberForNope() {
exampleCode drWho = new exampleCode();
User u = AwesomeTestLib.getUserWithProfile(‘SithProfile’);
Account a = (Account)TestFactory.createSObject(new Account());
Integer result;
System.runAs(u){
Test.startTest();
result = drWho.getBankAccount(a);
Test.stopTest();
}
System.assertEquals(result, null,
‘Expected Sith lords to be blocked’);
}
#forcewebinar
Principle #5, User Tests – w/ Permission set
@isTest
private class exampleCode_Tests {
@isTest static void test_getBankAccount_W_PermSet() {
exampleCode drWho = new exampleCode();
User u = AwesomeTestLib.getUserWithProfile(‘Standard User’);
UtilityClass.AssignUserToPermissionSet(u, ‘canReadBankAccount’);
Account a = (Account)TestFactory.createSObject(new Account());
Integer result;
System.runAs(u){
Test.startTest();
result = drWho.getBankAccount(a);
Test.stopTest();
}
System.assertNotEquals(result, null,
‘Expected user with canReadBankAccount to read BankAccount#’);
}
#forcewebinar
Principle #6, Use your own data
 Always build your own test data.
 Unless you have to, never use
@isTest(seeAllData=true)
 Rember you can dynamically write assertions:
– AssertEquals(AccountICreated.foo__c, ResultAccount.foo__c,
‘the two accounts should be the same!’);
#forcewebinar
Principle #6, Use your own data
 General pattern is to
– Create your test data
– Use that test data within your tested method
– Assert your code works as expected
#forcewebinar
Principle #6, Use your own data
 Tools to make this faster:
– TestFactory, An open source test data factory from Daniel
Hoechst. Found at http://bit.ly/1c5exnV
– Account a = (Account)TestFactory.createSObject(new
Account());
– Opportunity o = (Opportunity)TestFactory.createSObject(new
Opportunity(AccountId = a.Id));
– Account[] aList = (Account[])TestFactory.createSObjectList(new
Account(), 200);
#forcewebinar
Principle #7, Use a domain specific test helper lib
 Test Helpers facilitate faster test writing
 Additionally make tests easier to read, by abstracting
out superfluous code.
 Mark your test helper as @isTest to ensure it’s never
called by live code, and to ensure it’s not counted
against you in code coverage
#forcewebinar
Principle #7, Use a domain specific test helper lib
 Candidates for Test Helper classes include:
– Creating a user object with a given permission set assigned
– Generating complex object trees:
• generateAccountWOppAndProducts()
– Anything you do more than once in a test suite
– Make them public static methods and use a naming convention
• generate* - generates an object
• get* - retrieves an object via SOQL
#forcewebinar
Principle #8, Mocking
 Integration v. Unit tests
– Integration tests test code in an execution context – Ie setup
some data and execute the code within the context.
– Unit tests focus on a single unit of code, not necessarily a
complete function.
– Mocks allow us to write true unit tests by ‘mocking’ objects.
– You get to setup the mock, and it’s responses.
#forcewebinar
Principle #8, Mocking
Unit Test
Calls a
service
Returns
???
Traditional integration testing
#forcewebinar
Principle #8, Mocking
Unit testing with mocks
Mock
Obj
Unit
Test
Returns
known
result
Returns
known
result
#forcewebinar
Principle #8, Mocking
 Use mocks to insert objects whenever that object is not
critical to the test.
– For instance, if you’re testing a method that populates an
Account with the results of a webservice, mock out the web
services’ result.
– This allows you to test just what that method does to the
account object, not it’s ability to talk to a web service
#forcewebinar
Principle #8, Mocking
 Not just for webservices – Mock all services!
– Mock anything you have in your service layer
– Use interfaces and write the unit test with a mock
implementation
#forcewebinar
Principle #8, Mocking
@isTest
Public class exampleCode_Tests{
Public Boolean MockExample(Account a, Account b){
fflib_apexMocks m = new ffLib_apexMocks();
myInterface mock = new MockMyService(m);
m.startStubbing();
m.when(mock.add(5,7)).thenReturn(12);
m.stopStubbing();
Test.startTest();
ExampleCode mockObj = new exampleCode(myAwesomeService);
Integer result = mockObj.add(5,7);
Test.stopTest();
System.assertEquals(12, result, ‘friendly message’);
}
}
#forcewebinar
Principle #8, Mocking Part 2
 Mocking HTTP Responses
 Allows you to test HTTP Callouts without making the
Callout.
 Interface requires you to return an HTTP Response
object.
#forcewebinar
Principle #8, Mocking Part 2 – Use a factory
@isTest
public with sharing class HTTPMockCalloutFactory implements HttpCalloutMock {
HTTPMockCalloutFactory (Integer code, String status, String body, Map<String,
String> responseHeaders) {
// set class variables here.
}
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setStatusCode(this.code);
res.setStatus(this.status);
res.setBody(this.bodyAsString);
return res;
}
}
#forcewebinar
Principle #8, Mocking Part 2 – Use a factory
 You can even extend your factory to return different
response based on a static class variable. Useful for
testing multiple callout scenarios.
– Write an additional constructor that accepts a list of json strings
that de-serialize into responses
#forcewebinar
Principle #9, Write for testing
 Write small, tightly focused methods that play well with
others.
 Compose advanced functionality by using your small
methods together
 Write more-or-less unit tests with these focused
methods, and integration tests for customized logic.
#forcewebinar
Principle #9, Write for testing: guidelines
 Keep your methods to no more than 20 lines.
 Keep method arguments to a minimum – no more than
four.
 Write your Visualforce controllers to use a single
wrapper object.
– Either mock this wrapper object, or write a Test Helper method
to construct it.
 Use descriptive method names!
#forcewebinar
Principle #10, Use Continuous Integration!
 Continuous Integration is the idea that every code-
change committed to your source repository triggers a
full run of the tests.
 A number of tools are available for CI on the
Salesforce1 platform.
 Travis.ci, Drone.io, Jenkins and Codeship are some
examples
#forcewebinar
Principle #10, Use Continuous Integration!
 CI gives you insight to failing tests as soon as they’re
committed not when you try to deploy
 Facilitates multiple developers working on the same
project in their own sandboxes / dev orgs
 Keeps you aware of code coverage as development
occurs.
#forcewebinar
Useful tips
 Don’t insert or query unless you have to. You can often
test with objects in memory!
 Learn more about Mocking by watching Jesse Altman’s
(@JesseAltman) Excellent intro to mocking with Apex
mocks here: http://bit.ly/1HtXk2B
 Write and use a standardized Logging library that wraps
log data in a highly visible header/footer
#forcewebinar
Survey
Your feedback is crucial to the success
of our webinar programs. Thank you!
http://bit.ly/1FCyGiR
#forcewebinar
Q & A
Survey Link: http://bit.ly/1FCyGiR
Kevin Poorman
Principle Architect, EDL
Consulting
@Codefriar
Thank You

More Related Content

What's hot

Mastering Force.com: Advanced Visualforce
Mastering Force.com: Advanced VisualforceMastering Force.com: Advanced Visualforce
Mastering Force.com: Advanced Visualforce
Salesforce Developers
 
Salesforce.com API Series: Service Cloud Console Deep Dive
Salesforce.com API Series: Service Cloud Console Deep DiveSalesforce.com API Series: Service Cloud Console Deep Dive
Salesforce.com API Series: Service Cloud Console Deep Dive
Salesforce Developers
 
Secure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding MistakesSecure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding Mistakes
Salesforce Developers
 
Coding in the App Cloud
Coding in the App CloudCoding in the App Cloud
Coding in the App Cloud
Salesforce Developers
 
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
Salesforce Developers
 
Process Automation on Lightning Platform Workshop
Process Automation on Lightning Platform WorkshopProcess Automation on Lightning Platform Workshop
Process Automation on Lightning Platform Workshop
Salesforce Developers
 
Build Better Communities with Lightning
Build Better Communities with LightningBuild Better Communities with Lightning
Build Better Communities with Lightning
Salesforce Developers
 
Advanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesAdvanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous Processes
Salesforce Developers
 
SLDS and Lightning Components
SLDS and Lightning ComponentsSLDS and Lightning Components
SLDS and Lightning Components
Salesforce Developers
 
Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3
Mark Adcock
 
Integrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST ServicesIntegrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST Services
Salesforce Developers
 
Building apps faster with lightning and winter '17
Building apps faster with lightning and winter '17Building apps faster with lightning and winter '17
Building apps faster with lightning and winter '17
Salesforce Developers
 
Integrating with salesforce
Integrating with salesforceIntegrating with salesforce
Integrating with salesforce
Mark Adcock
 
Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2
Salesforce Developers
 
Modeling and Querying Data and Relationships in Salesforce
Modeling and Querying Data and Relationships in SalesforceModeling and Querying Data and Relationships in Salesforce
Modeling and Querying Data and Relationships in Salesforce
Salesforce Developers
 
Streamline Selenium Testing with Page Flow Navigation
Streamline Selenium Testing with Page Flow NavigationStreamline Selenium Testing with Page Flow Navigation
Streamline Selenium Testing with Page Flow Navigation
Salesforce Developers
 
Migrating Visualforce Pages to Lightning
Migrating Visualforce Pages to LightningMigrating Visualforce Pages to Lightning
Migrating Visualforce Pages to Lightning
Salesforce Developers
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
Salesforce Developers
 
Building a Single Page App with Lightning Components
Building a Single Page App with Lightning ComponentsBuilding a Single Page App with Lightning Components
Building a Single Page App with Lightning Components
Salesforce Developers
 
Elevate workshop programmatic_2014
Elevate workshop programmatic_2014Elevate workshop programmatic_2014
Elevate workshop programmatic_2014David Scruggs
 

What's hot (20)

Mastering Force.com: Advanced Visualforce
Mastering Force.com: Advanced VisualforceMastering Force.com: Advanced Visualforce
Mastering Force.com: Advanced Visualforce
 
Salesforce.com API Series: Service Cloud Console Deep Dive
Salesforce.com API Series: Service Cloud Console Deep DiveSalesforce.com API Series: Service Cloud Console Deep Dive
Salesforce.com API Series: Service Cloud Console Deep Dive
 
Secure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding MistakesSecure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding Mistakes
 
Coding in the App Cloud
Coding in the App CloudCoding in the App Cloud
Coding in the App Cloud
 
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
Apex for Admins: Get Started with Apex in 30 Minutes! (part 1)
 
Process Automation on Lightning Platform Workshop
Process Automation on Lightning Platform WorkshopProcess Automation on Lightning Platform Workshop
Process Automation on Lightning Platform Workshop
 
Build Better Communities with Lightning
Build Better Communities with LightningBuild Better Communities with Lightning
Build Better Communities with Lightning
 
Advanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesAdvanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous Processes
 
SLDS and Lightning Components
SLDS and Lightning ComponentsSLDS and Lightning Components
SLDS and Lightning Components
 
Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3
 
Integrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST ServicesIntegrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST Services
 
Building apps faster with lightning and winter '17
Building apps faster with lightning and winter '17Building apps faster with lightning and winter '17
Building apps faster with lightning and winter '17
 
Integrating with salesforce
Integrating with salesforceIntegrating with salesforce
Integrating with salesforce
 
Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2
 
Modeling and Querying Data and Relationships in Salesforce
Modeling and Querying Data and Relationships in SalesforceModeling and Querying Data and Relationships in Salesforce
Modeling and Querying Data and Relationships in Salesforce
 
Streamline Selenium Testing with Page Flow Navigation
Streamline Selenium Testing with Page Flow NavigationStreamline Selenium Testing with Page Flow Navigation
Streamline Selenium Testing with Page Flow Navigation
 
Migrating Visualforce Pages to Lightning
Migrating Visualforce Pages to LightningMigrating Visualforce Pages to Lightning
Migrating Visualforce Pages to Lightning
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
 
Building a Single Page App with Lightning Components
Building a Single Page App with Lightning ComponentsBuilding a Single Page App with Lightning Components
Building a Single Page App with Lightning Components
 
Elevate workshop programmatic_2014
Elevate workshop programmatic_2014Elevate workshop programmatic_2014
Elevate workshop programmatic_2014
 

Similar to 10 Principles of Apex Testing

10 principles of apex testing
10 principles of apex testing10 principles of apex testing
10 principles of apex testing
Kevin Poorman
 
10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex TestingKevin Poorman
 
10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex Testing
Salesforce Developers
 
Advanced Apex Webinar
Advanced Apex WebinarAdvanced Apex Webinar
Advanced Apex Webinar
pbattisson
 
Dive Deep into Apex: Advanced Apex!
Dive Deep into Apex: Advanced Apex! Dive Deep into Apex: Advanced Apex!
Dive Deep into Apex: Advanced Apex!
Salesforce Developers
 
Apex Testing Best Practices
Apex Testing Best PracticesApex Testing Best Practices
Apex Testing Best Practices
Salesforce Developers
 
Apex for Admins: Beyond the Basics
Apex for Admins: Beyond the BasicsApex for Admins: Beyond the Basics
Apex for Admins: Beyond the Basics
Salesforce Developers
 
Generating Test Cases
Generating Test CasesGenerating Test Cases
Generating Test Cases
VivekRajawat9
 
Intro to Apex Programmers
Intro to Apex ProgrammersIntro to Apex Programmers
Intro to Apex Programmers
Salesforce Developers
 
Apex 10 commandments df14
Apex 10 commandments df14Apex 10 commandments df14
Apex 10 commandments df14
Kevin Poorman
 
Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015
Samuel De Rycke
 
Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016
Laura Meerkatz
 
iOS Unit Testing Like a Boss
iOS Unit Testing Like a BossiOS Unit Testing Like a Boss
iOS Unit Testing Like a Boss
Salesforce Developers
 
Finding Security Issues Fast!
Finding Security Issues Fast!Finding Security Issues Fast!
Finding Security Issues Fast!
Salesforce Engineering
 
Quit Jesting and Test your Lightning Web Components, Phillipe Ozil
Quit Jesting and Test your Lightning Web Components, Phillipe OzilQuit Jesting and Test your Lightning Web Components, Phillipe Ozil
Quit Jesting and Test your Lightning Web Components, Phillipe Ozil
CzechDreamin
 
Continuous Integration In The Cloud Final (1)
Continuous Integration In The Cloud Final (1)Continuous Integration In The Cloud Final (1)
Continuous Integration In The Cloud Final (1)
Alexis Williams
 
Introduction to Apex Triggers
Introduction to Apex TriggersIntroduction to Apex Triggers
Introduction to Apex Triggers
Salesforce Developers
 
Df14 Building Machine Learning Systems with Apex
Df14 Building Machine Learning Systems with ApexDf14 Building Machine Learning Systems with Apex
Df14 Building Machine Learning Systems with Apex
pbattisson
 

Similar to 10 Principles of Apex Testing (20)

10 principles of apex testing
10 principles of apex testing10 principles of apex testing
10 principles of apex testing
 
10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex Testing
 
10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex Testing
 
Advanced Apex Webinar
Advanced Apex WebinarAdvanced Apex Webinar
Advanced Apex Webinar
 
Dive Deep into Apex: Advanced Apex!
Dive Deep into Apex: Advanced Apex! Dive Deep into Apex: Advanced Apex!
Dive Deep into Apex: Advanced Apex!
 
Apex Testing Best Practices
Apex Testing Best PracticesApex Testing Best Practices
Apex Testing Best Practices
 
Apex Unit Testing in the Real World
Apex Unit Testing in the Real WorldApex Unit Testing in the Real World
Apex Unit Testing in the Real World
 
Apex for Admins: Beyond the Basics
Apex for Admins: Beyond the BasicsApex for Admins: Beyond the Basics
Apex for Admins: Beyond the Basics
 
Generating Test Cases
Generating Test CasesGenerating Test Cases
Generating Test Cases
 
Intro to Apex Programmers
Intro to Apex ProgrammersIntro to Apex Programmers
Intro to Apex Programmers
 
Apex 10 commandments df14
Apex 10 commandments df14Apex 10 commandments df14
Apex 10 commandments df14
 
Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015Asynchronous Apex Salesforce World Tour Paris 2015
Asynchronous Apex Salesforce World Tour Paris 2015
 
Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016
 
iOS Unit Testing Like a Boss
iOS Unit Testing Like a BossiOS Unit Testing Like a Boss
iOS Unit Testing Like a Boss
 
Finding Security Issues Fast!
Finding Security Issues Fast!Finding Security Issues Fast!
Finding Security Issues Fast!
 
Quit Jesting and Test your Lightning Web Components, Phillipe Ozil
Quit Jesting and Test your Lightning Web Components, Phillipe OzilQuit Jesting and Test your Lightning Web Components, Phillipe Ozil
Quit Jesting and Test your Lightning Web Components, Phillipe Ozil
 
Continuous Integration In The Cloud Final (1)
Continuous Integration In The Cloud Final (1)Continuous Integration In The Cloud Final (1)
Continuous Integration In The Cloud Final (1)
 
Introduction to Apex Triggers
Introduction to Apex TriggersIntroduction to Apex Triggers
Introduction to Apex Triggers
 
Introduction to Apex Triggers
Introduction to Apex TriggersIntroduction to Apex Triggers
Introduction to Apex Triggers
 
Df14 Building Machine Learning Systems with Apex
Df14 Building Machine Learning Systems with ApexDf14 Building Machine Learning Systems with Apex
Df14 Building Machine Learning Systems with Apex
 

More from Salesforce Developers

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Salesforce Developers
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
Salesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
Salesforce Developers
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
Salesforce Developers
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
Salesforce Developers
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
Salesforce Developers
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
Salesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
Salesforce Developers
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
Salesforce Developers
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
Salesforce Developers
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
Salesforce Developers
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
Salesforce Developers
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
Salesforce Developers
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
Salesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
Salesforce Developers
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
Salesforce Developers
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
Salesforce Developers
 
Introduction to MuleSoft
Introduction to MuleSoftIntroduction to MuleSoft
Introduction to MuleSoft
Salesforce Developers
 
Modern App Dev: Modular Development Strategies
Modern App Dev: Modular Development StrategiesModern App Dev: Modular Development Strategies
Modern App Dev: Modular Development Strategies
Salesforce Developers
 

More from Salesforce Developers (20)

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
 
Introduction to MuleSoft
Introduction to MuleSoftIntroduction to MuleSoft
Introduction to MuleSoft
 
Modern App Dev: Modular Development Strategies
Modern App Dev: Modular Development StrategiesModern App Dev: Modular Development Strategies
Modern App Dev: Modular Development Strategies
 

Recently uploaded

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 

Recently uploaded (20)

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 

10 Principles of Apex Testing

  • 1. 10 Principles of Apex Testing May 21st, 2015
  • 3. #forcewebinar Safe Harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward- looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  • 4. #forcewebinar Go Social! Salesforce Developers +Salesforce Developers Salesforce Developers Salesforce Developers The video will be posted to YouTube & the webinar recap page (same URL as registration). This webinar is being recorded! @salesforcedevs / #forcewebinar So make sure to leave comments on YouTube
  • 5. #forcewebinar ▪ Don’t wait until the end to ask your question! – Technical support will answer questions starting now. ▪ Respect Q&A etiquette – Please don’t repeat questions. The support team is working their way down the queue. ▪ Stick around for live Q&A at the end – Speakers will tackle more questions at the end, time- allowing. If no one asks questions, Kevin will. ▪ Head to Developer Forums – More questions? Visit developer.salesforce.com/forums Have Questions?
  • 6. #forcewebinar Agenda 1. Why we do Testing 2. 10 principles of Apex Testing 3. Questions and Answers
  • 8. #forcewebinar Why we test?  Tests provide assurance of functionality  Tests reduce cost of change  Tests encourage modular, reusable code  Tests help identify engineering and architectural bugs  Tests help document expected behavior  Tests + Code = less likely to produce bugs
  • 9. #forcewebinar Principle #1, Use Asserts  A test without Assert methods isn’t a test, it’s code execution  Three Assert methods built-in – System.Assert(boolean-expression, ‘friendly message’) – System.AssertEquals(expect, actual, ‘friendly message’) – System.AssertNotEquals(expected, actual, ‘friendly message)  Every test method should include at least one assertion
  • 10. #forcewebinar Principle #1, Use Asserts You can write your own assert methods! @isTest Public class customAssertions{ public class customAssertionException extends Exception{} Public Boolean DuplicateAccount(Account a, Account b){ // … compare accounts if(duplicate != true) { Throw new customAssertionException(‘whoa, it’s not the same’); } return true; } }
  • 11. #forcewebinar Principle #2, use startTest and stopTest  Test.startTest() and Test.stopTest() help facilitate testing.  startTest() resets DML, CPU Time and other governor limits, ensuring any limits you hit come from your tested code!  stopTest() Forces asynchronous code to complete.
  • 12. #forcewebinar Principle #2, use startTest and stopTest  General pattern is to – Create your test data – Start the test – Use that test data within your tested method – End the Test – Assert your code works as expected
  • 13. #forcewebinar Principle #3, Positive Tests  Write ‘Positive Tests’  Positive tests test the expected behavior  Lets talk about multiple expected behaviors  Not just happy path testing
  • 14. #forcewebinar Principle #3, Positive Tests Public class exampleCode { Public Integer add(Integer one, Integer two){ return one + two; } }
  • 15. #forcewebinar Principle #3, Positive Tests @isTest private class exampleCode_Tests { @isTest static void test_Add_Postive() { exampleCode drWho = new exampleCode(); Test.startTest(); Integer testValue = drWho.add(5,7); Test.stopTest(); System.assertEquals(12, testValue, ‘Expected 5+7 to equal 12’); }
  • 16. #forcewebinar Principle #4, Negative Tests  Negative tests prove that your code properly handles exceptions and errors.  The general pattern is to call your method within a try/catch block in the test. Since you expect an exception you’ll catch it in the catch block  Less intuitive but more powerful!
  • 17. #forcewebinar Principle #4, Negative Tests Public class exampleCode { Public class exampleCodeException{} Public Integer division(Integer one, Integer two){ if(two == 0) { Throw new exampleCodeException(‘Dividing by zero makes kittens cry’); } return one / two; } }
  • 18. #forcewebinar Principle #4, Negative Tests @isTest private class exampleCode_Tests { @isTest static void test_Divide_Negative() { exampleCode drWho = new exampleCode(); Boolean didCatchProperException = false; Test.startTest(); Try { drWho.divide(1, 0); } catch (exampleCodeException AwesomeException){ didCatchProperException = true; } Test.stopTest(); System.assert(didCatchProperException, ‘Properly caught custom Exception’); }
  • 19. #forcewebinar Principle #5, User Tests  User based tests prove your security model  Test with Users of different Roles / Profiles and Permission sets!  The pattern works like this: Create a user with a given profile. As needed assign permission sets. Test both positive and negative users.
  • 20. #forcewebinar Principle #5, User Tests Public class exampleCode { Public class exampleCodeException{} Public Integer getBankAccount(Account a){ return a.SuperSecretBankAccountNum__c; } }
  • 21. #forcewebinar Principle #5, User Tests Positive @isTest private class exampleCode_Tests { @isTest static void test_getBankAccount_Positive() { exampleCode drWho = new exampleCode(); User u = AwesomeTestLib.getUserWithProfile(‘JediProfile’); Account a = (Account)TestFactory.createSObject(new Account()); Integer result; System.runAs(u){ Test.startTest(); result = drWho.getBankAccount(a); Test.stopTest(); } System.assertNotEquals(result, null, ‘Expected this user to have access to bank #’); }
  • 22. #forcewebinar Principle #5, User Tests - Negative @isTest private class exampleCode_Tests { @isTest static void test_getBankAccount_UberForNope() { exampleCode drWho = new exampleCode(); User u = AwesomeTestLib.getUserWithProfile(‘SithProfile’); Account a = (Account)TestFactory.createSObject(new Account()); Integer result; System.runAs(u){ Test.startTest(); result = drWho.getBankAccount(a); Test.stopTest(); } System.assertEquals(result, null, ‘Expected Sith lords to be blocked’); }
  • 23. #forcewebinar Principle #5, User Tests – w/ Permission set @isTest private class exampleCode_Tests { @isTest static void test_getBankAccount_W_PermSet() { exampleCode drWho = new exampleCode(); User u = AwesomeTestLib.getUserWithProfile(‘Standard User’); UtilityClass.AssignUserToPermissionSet(u, ‘canReadBankAccount’); Account a = (Account)TestFactory.createSObject(new Account()); Integer result; System.runAs(u){ Test.startTest(); result = drWho.getBankAccount(a); Test.stopTest(); } System.assertNotEquals(result, null, ‘Expected user with canReadBankAccount to read BankAccount#’); }
  • 24. #forcewebinar Principle #6, Use your own data  Always build your own test data.  Unless you have to, never use @isTest(seeAllData=true)  Rember you can dynamically write assertions: – AssertEquals(AccountICreated.foo__c, ResultAccount.foo__c, ‘the two accounts should be the same!’);
  • 25. #forcewebinar Principle #6, Use your own data  General pattern is to – Create your test data – Use that test data within your tested method – Assert your code works as expected
  • 26. #forcewebinar Principle #6, Use your own data  Tools to make this faster: – TestFactory, An open source test data factory from Daniel Hoechst. Found at http://bit.ly/1c5exnV – Account a = (Account)TestFactory.createSObject(new Account()); – Opportunity o = (Opportunity)TestFactory.createSObject(new Opportunity(AccountId = a.Id)); – Account[] aList = (Account[])TestFactory.createSObjectList(new Account(), 200);
  • 27. #forcewebinar Principle #7, Use a domain specific test helper lib  Test Helpers facilitate faster test writing  Additionally make tests easier to read, by abstracting out superfluous code.  Mark your test helper as @isTest to ensure it’s never called by live code, and to ensure it’s not counted against you in code coverage
  • 28. #forcewebinar Principle #7, Use a domain specific test helper lib  Candidates for Test Helper classes include: – Creating a user object with a given permission set assigned – Generating complex object trees: • generateAccountWOppAndProducts() – Anything you do more than once in a test suite – Make them public static methods and use a naming convention • generate* - generates an object • get* - retrieves an object via SOQL
  • 29. #forcewebinar Principle #8, Mocking  Integration v. Unit tests – Integration tests test code in an execution context – Ie setup some data and execute the code within the context. – Unit tests focus on a single unit of code, not necessarily a complete function. – Mocks allow us to write true unit tests by ‘mocking’ objects. – You get to setup the mock, and it’s responses.
  • 30. #forcewebinar Principle #8, Mocking Unit Test Calls a service Returns ??? Traditional integration testing
  • 31. #forcewebinar Principle #8, Mocking Unit testing with mocks Mock Obj Unit Test Returns known result Returns known result
  • 32. #forcewebinar Principle #8, Mocking  Use mocks to insert objects whenever that object is not critical to the test. – For instance, if you’re testing a method that populates an Account with the results of a webservice, mock out the web services’ result. – This allows you to test just what that method does to the account object, not it’s ability to talk to a web service
  • 33. #forcewebinar Principle #8, Mocking  Not just for webservices – Mock all services! – Mock anything you have in your service layer – Use interfaces and write the unit test with a mock implementation
  • 34. #forcewebinar Principle #8, Mocking @isTest Public class exampleCode_Tests{ Public Boolean MockExample(Account a, Account b){ fflib_apexMocks m = new ffLib_apexMocks(); myInterface mock = new MockMyService(m); m.startStubbing(); m.when(mock.add(5,7)).thenReturn(12); m.stopStubbing(); Test.startTest(); ExampleCode mockObj = new exampleCode(myAwesomeService); Integer result = mockObj.add(5,7); Test.stopTest(); System.assertEquals(12, result, ‘friendly message’); } }
  • 35. #forcewebinar Principle #8, Mocking Part 2  Mocking HTTP Responses  Allows you to test HTTP Callouts without making the Callout.  Interface requires you to return an HTTP Response object.
  • 36. #forcewebinar Principle #8, Mocking Part 2 – Use a factory @isTest public with sharing class HTTPMockCalloutFactory implements HttpCalloutMock { HTTPMockCalloutFactory (Integer code, String status, String body, Map<String, String> responseHeaders) { // set class variables here. } public HTTPResponse respond(HTTPRequest req) { HttpResponse res = new HttpResponse(); res.setStatusCode(this.code); res.setStatus(this.status); res.setBody(this.bodyAsString); return res; } }
  • 37. #forcewebinar Principle #8, Mocking Part 2 – Use a factory  You can even extend your factory to return different response based on a static class variable. Useful for testing multiple callout scenarios. – Write an additional constructor that accepts a list of json strings that de-serialize into responses
  • 38. #forcewebinar Principle #9, Write for testing  Write small, tightly focused methods that play well with others.  Compose advanced functionality by using your small methods together  Write more-or-less unit tests with these focused methods, and integration tests for customized logic.
  • 39. #forcewebinar Principle #9, Write for testing: guidelines  Keep your methods to no more than 20 lines.  Keep method arguments to a minimum – no more than four.  Write your Visualforce controllers to use a single wrapper object. – Either mock this wrapper object, or write a Test Helper method to construct it.  Use descriptive method names!
  • 40. #forcewebinar Principle #10, Use Continuous Integration!  Continuous Integration is the idea that every code- change committed to your source repository triggers a full run of the tests.  A number of tools are available for CI on the Salesforce1 platform.  Travis.ci, Drone.io, Jenkins and Codeship are some examples
  • 41. #forcewebinar Principle #10, Use Continuous Integration!  CI gives you insight to failing tests as soon as they’re committed not when you try to deploy  Facilitates multiple developers working on the same project in their own sandboxes / dev orgs  Keeps you aware of code coverage as development occurs.
  • 42. #forcewebinar Useful tips  Don’t insert or query unless you have to. You can often test with objects in memory!  Learn more about Mocking by watching Jesse Altman’s (@JesseAltman) Excellent intro to mocking with Apex mocks here: http://bit.ly/1HtXk2B  Write and use a standardized Logging library that wraps log data in a highly visible header/footer
  • 43.
  • 44. #forcewebinar Survey Your feedback is crucial to the success of our webinar programs. Thank you! http://bit.ly/1FCyGiR
  • 45. #forcewebinar Q & A Survey Link: http://bit.ly/1FCyGiR Kevin Poorman Principle Architect, EDL Consulting @Codefriar