SlideShare a Scribd company logo
1 of 46
Download to read offline
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
10 Principles of Apex Testing
#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 VisualforceSalesforce 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 DiveSalesforce Developers
 
Secure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding MistakesSecure Salesforce: Common Secure Coding Mistakes
Secure Salesforce: Common Secure Coding MistakesSalesforce 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 WorkshopSalesforce Developers
 
Build Better Communities with Lightning
Build Better Communities with LightningBuild Better Communities with Lightning
Build Better Communities with LightningSalesforce Developers
 
Advanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesAdvanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesSalesforce 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 3Mark 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 ServicesSalesforce 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 '17Salesforce Developers
 
Integrating with salesforce
Integrating with salesforceIntegrating with salesforce
Integrating with salesforceMark 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 2Salesforce 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 SalesforceSalesforce 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 NavigationSalesforce Developers
 
Migrating Visualforce Pages to Lightning
Migrating Visualforce Pages to LightningMigrating Visualforce Pages to Lightning
Migrating Visualforce Pages to LightningSalesforce 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 InteroperabilitySalesforce 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 ComponentsSalesforce 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 testingKevin Poorman
 
10 Principles of Apex Testing
10 Principles of Apex Testing10 Principles of Apex Testing
10 Principles of Apex TestingKevin Poorman
 
Advanced Apex Webinar
Advanced Apex WebinarAdvanced Apex Webinar
Advanced Apex Webinarpbattisson
 
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
 
Generating Test Cases
Generating Test CasesGenerating Test Cases
Generating Test CasesVivekRajawat9
 
Apex 10 commandments df14
Apex 10 commandments df14Apex 10 commandments df14
Apex 10 commandments df14Kevin 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 2015Samuel De Rycke
 
Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016Intro to Apex Testing - Dreamforce 2016
Intro to Apex Testing - Dreamforce 2016Laura Meerkatz
 
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 OzilCzechDreamin
 
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
 
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 Apexpbattisson
 

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 DevelopersSalesforce 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 PerformanceSalesforce 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 ComponentsSalesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsSalesforce 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 IndiaSalesforce 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 DevelopmentSalesforce 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 ComponentsSalesforce 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 ComponentsSalesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsSalesforce 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 TestingSalesforce 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 IntroductionSalesforce 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 JSQCPSalesforce 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 SalesforceSalesforce 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 CaptureSalesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DXSalesforce 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 ConnectSalesforce Developers
 
Modern App Dev: Modular Development Strategies
Modern App Dev: Modular Development StrategiesModern App Dev: Modular Development Strategies
Modern App Dev: Modular Development StrategiesSalesforce 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

ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 

Recently uploaded (20)

ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 

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
  • 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