Salesforce Platform Developer I
概述
吸取platform app builder学习笔记的教训,在简书没有修改对于收费文章的准入门槛之前,直接用英语做复习笔记,提高备考效率。部分个人心得可能会用中文。
考试范围
SALESFORCE FUNDAMENTALS (10%)
Describe the considerations when developing in a multi-tenant environment
Describe how the Salesforce platform features map to the MVC pattern.
http://www.salesforcegeneral.com/salesforce-mvc-explained/
Describe the capabilities of the core CRM objects in the Salesforce schema.
Identify the common scenarios for extending an application's capabilities using the AppExchange.
Attribute | Managed Packages | Unmanaged Packages |
---|---|---|
Customization | You can’t view or change the offering’s code or metadata. | You can customize code and metadata, if desired. |
Upgrades | The provider can automatically upgrade the offering. | To receive an upgrade, you must uninstall the package from your org and then reinstall a new version from AppExchange. |
Org limits | The contents of the package don’t count against the app, tab, and object limits in your org. | The contents of the package count against the app, tab, and object limits in your org. |
The only requirement to create a managed package is that you’re using a Developer Edition organization.
Identify common use cases for declarative customization of the Lightning Platform, and customization and features of the Heroku platform.
Identify whether to use formula, roll-up summary, validation rule, workflow rule, process builder, visual workflow or approval process
Heroku (PaaS)
DATA MODELING AND MANAGEMENT (12%)
Given a set of requirements, determine the appropriate data model.
Lookup Relationship
Can be one-to-one or one-to-many.
Use lookup relationships when objects are only related in some cases.
Objects in lookup relationships usually work as stand-alone objects and have their own tabs in the user interface
Master-Detail Relationship
The master object controls certain behaviors of the detail object.
When you’re creating master-detail relationships, you always create the relationship field on the detail object.
Junction Object
A custom object with two master-detail relationships. Using a custom junction object, you can model a “many-to-many” relationship between two objects.
Creating the many-to-many relationship consists of:
-
Creating the junction object.
a. Junction Objects do not need a tab. -
Creating the two master-detail relationships.
The first master-detail relationship you create on your junction object becomes the primary relationship. This affects the following for the junction object records:
a. Look and feel: The junction object's detail and edit pages use the color and any associated icon of the primary master object.
b.Record ownership: The junction object records inherit the value of the Owner field from their associated primary master record. Because objects on the detail side of a relationship do not have a visible Owner field, this is only relevant if you later delete both master-detail relationships on your junction object.
c. Division: If your organization uses divisions to segment data, the junction object records inherit their division from their associated primary master record. Similar to the record ownership, this is only relevant if you later delete both master-detail relationships.
The second master-detail relationship you create on your junction object becomes the secondary relationship. If you delete the primary master-detail relationship or convert it to a lookup relationship, the secondary master object becomes primary. -
Customizing the related lists on the page layouts of the two master objects.
For the Related List Label that will display on the page layout of the master object, do not accept the default. Change this to use the name of the other master object in your many-to-many relationship. -
Customizing reports to maximize the effectiveness of the many-to-many relationship.
Many-to-many relationships provide two standard report types that join the master objects and the junction object. The report types are:- “Primary master with junction object and secondary master” in the primary master object's report category.
- “Secondary master with junction object and primary master” in the secondary master object's report category.
Describe the capabilities of the various relationship types and the implications of each on record access, user interface (UI), and object-oriented programming.
Relationship Limits
Each custom object can have up to two master-detail relationships and many lookup relationships. Each relationship is included in the maximum number of custom fields allowed.
Converting Relationships
You can convert a master-detail relationship to a lookup relationship as long as no roll-up summary fields exist on the master object.
You can convert a lookup relationship to a master-detail relationship, but only if the lookup field in all records contains a value.
Self Relationships
You can create a relationship from an object to itself, but it must be a lookup relationship, and a single record can't be linked to itself. However, a record can indirectly relate to itself.
You can't create a many-to-many self relationship, that is, the two master-detail relationships on the junction object can't have the same master object.
Icons for Custom Related Lists
The icon you select for the associated custom tab also **displays in any custom related list **you create based on a relationship.
Custom related lists do not include an icon if they are based on a relationship with a custom object that does not have a custom tab.
Master-Detail Relationships
To create multilevel master-detail relationships, you need the “Customize Application” user permission.
By default, records can’t be reparented in master-detail relationships. Administrators can, however, allow child records in master-detail relationships on custom objects to be reparented to different parent records by selecting the Allow reparenting option in the master-detail relationship definition.
You can have up to three custom detail levels.
An object can appear once in multilevel master-detail relationships.
Multilevel master-detail relationships do not support division transfers.
Custom junction objects can't have detail objects.
You can’t delete a custom object if it is on the master side of a master-detail relationship. If you delete a custom object that is on the detail side of a master-detail relationship, the relationship is converted to a lookup relationship.
As a best practice, don't exceed 10,000 child records for a master-detail relationship.
Many-to-Many Relationships
Junction object records are deleted when either associated master record is deleted and placed in the Recycle Bin. If both associated master records are deleted, the junction object record is deleted permanently and can't be restored.</dd>
Sharing access to a junction object record is determined by a user's sharing access to both associated master records and the Sharing Setting option on the relationship field. See Custom Object Security. For example, if the sharing setting on both parents is Read/Write, then the user must have Read/Write access to both parents in order to have Read/Write access to the junction object. If, on the other hand, the sharing set
Roll-up summary fields that summarize data from the junction object can be created on both master objects.
Formula fields and validation rules on the junction object can reference fields on both master objects.
You can define Apex triggers on both master objects and the junction object.
You can't create a many-to-many self relationship, that is, the two master-detail relationships on the junction object can't have the same master object.</dd>
Lookup Relationships
If the lookup field is optional, you can specify one of three behaviors to occur if the lookup record is deleted:
- Clear the value of this field This is the default. Clearing the field is a good choice when the field does not have to contain a value from the associated lookup record.
- Don’t allow deletion of the lookup record that’s part of a lookup relationship This option restricts the lookup record from being deleted if you have any dependencies, such as a workflow rule, built on the relationship.
- Delete this record also Available only if a custom object contains the lookup relationship, not if it’s contained by a standard object. However, the lookup object can be either standard or custom. Choose when the lookup field and its associated record are tightly coupled and you want to completely delete related data. Contact Salesforce to get the cascade-delete option enabled for your organization. Cascade-delete and its related options are not available for lookup relationships to business hours, community, lead, price book, product, or user objects.
In a chain of lookup relationships, these behaviors work independently on each target field at each level.
In a multilevel lookup relationship, these options might conflict. For example, in the scenario where field A is the target lookup of field B, which in turn is the target lookup of field C, you might specify that A can delete B, but B cannot be deleted because it’s in a relationship with C. If you try to delete A, you’ll get an error saying that B can’t be deleted because it’s linked to C.
If the parent record in a lookup relationship is deleted, the field history tracking for the child record does not record the deletion.
Relationships on External Objects
Lookup, external lookup, and indirect lookup relationships have some special behaviors and limitations.
-
Only lookup, external lookup, and indirect lookup relationships are available for external objects. No other relationship types are supported.
-
Depending on the availability of the external system, related lists of child external objects may load slowly when users view the parent record detail pages.
-
Relationships that involve external objects allow users to create child records from the record detail pages of parent records. However, the relationship field on each new child record isn’t automatically populated to identify the parent record.
-
Syncing doesn’t create relationship fields on the external objects in your Salesforce org. However, you can change the field type of a sync-created custom field to Lookup Relationship, External Lookup Relationship, or Indirect Lookup Relationship. Changing the field type of an existing custom field is simpler and more efficient than manually creating a relationship field on the external object. For example, suppose that the external system has a foreign key relationship. Syncing the related tables creates a text field in your org for the external column that identifies the foreign keys. To reflect the foreign key relationship within your org, change the field type of that text field to External Lookup Relationship.
-
A relationship field is a type of custom field. Therefore, like all custom fields on an external object, relationship fields can be overwritten when you sync the external object. See the sync considerations for each Salesforce Connect adapter that you use.
-
Cascade-delete isn’t available for external object relationships.
-
In Salesforce Classic, indirect lookup relationship fields don’t display the expected names of parent records. Instead, each indirect lookup relationship field displays the value of the target field on the parent object. To find related records, target field values are matched against the values of the indirect lookup relationship field on the child object. The target field, which has Unique attributes, is selected when an indirect lookup relationship field is created.
-
In Salesforce Classic, external lookup relationship fields don’t always display the expected names of parent records.
- In a list view, an external lookup relationship field displays the parent object ID or the value of the parent object’s External ID standard field. The latter appears by default, but if a custom field on the parent object has the Is Name Field attribute, the parent object ID is displayed.
- In a record detail page, an external lookup relationship field displays the name as expected if the org has previously retrieved the parent record. If you see an ID in an external lookup relationship field, reload the page to replace the ID with the name.
-
Lookup search isn’t available for external lookup relationship fields. To edit an external lookup relationship field, manually enter the value of the External ID standard field for the parent record. This limitation doesn’t apply when the parent external object is associated with the cross-org adapter for Salesforce Connect.
-
Lookup search isn’t available for indirect lookup relationship fields. To edit an indirect lookup relationship field, manually enter the value of the target field of the parent record. The target field is the custom field with External ID and Unique attributes that was selected when the indirect lookup relationship was created. To determine related records, Salesforce matches target field values against the values of the indirect lookup relationship field on the child object.
-
With external lookup and indirect lookup relationships, the parent record appears as a clickable link in the relationship field on the child record. If the child record is viewed by a user who doesn’t have access to the parent record, the parent record appears in the relationship field as plain text instead of a link.
-
Lookup filters aren’t available for external lookup relationship fields.
-
Indirect lookup relationship fields can be created on external objects only.
-
Only objects that have a custom field with the External ID and Unique attributes are available as parent objects in indirect lookup relationships. If you don't see the desired object when you create an indirect lookup relationship field, add a custom unique, external ID field to that object.
-
If the external system uses case-sensitive values in the specified External Column Name, make sure that the parent object field is also case-sensitive. When you define the parent object’s custom field, select External ID, Unique, and Treat "ABC" and "abc" as different values (case sensitive).
Impact of Relationship on Reports
- Lookup relationships allow data from the two related objects to be joined in one report.
- Master-detail relationships allow data from three objects to be joined in one report: the master object, the detail object, plus one other lookup object. If the detail object has multiple lookup relationships, a separate report type is available based on each lookup.
- Many-to-many relationships provide two standard report types that join the master objects and the junction object. The report types are:
- “Primary master with junction object and secondary master” in the primary master object's report category.
- “Secondary master with junction object and primary master” in the secondary master object's report category.
The order of the master objects in the report type is important. The master object listed first determines the scope of records that can be displayed in the report.
Note that converting a relationship from lookup to master-detail or vice versa can cause existing custom reports to become unusable due to the different standard report types available for each type of relationship. We recommend that you test your custom reports immediately after converting the relationship type. If you revert your relationship back to the original type, the reports are restored and become usable again.
Describe the impact of schema design and modifications on Apex Development.
Describe how to visualize and create entity relationships.
Schema Builder is a tool that lets you visualize and edit your data model.
You can manage the permissions for your custom fields directly in Schema Builder. Just right-click the field name and click Manage Field Permissions.
You can also create objects using Schema Builder (Elements -> Object/Field Type->Canvas->Enter Info ->Save).
Describe the options for and considerations when importing and exporting data into development environments.
LOGIC AND PROCESS AUTOMATION (46%)
Describe how to programmatically access and utilize the object schema.
-
Access sObject and field describe information
a. token (lightweight, serializable, validated at compile time, describes SObject or field), Schema.describeSObjects() - describe one or more SObject, Schema.DescribeSObjectResult - not serializable, and are validated at runtime, describes SObject or field.
b. Use the Schema getGlobalDescribe method to return a map that represents the relationship between all sObject names (keys) to sObject tokens (values).
For example:
Map<String, Schema.SObjectField> fieldMap = Schema.SObjectType.Account.fields.getMap();
-
Access Salesforce app information
Each app corresponds to a collection of tabs. Describe information for an app includes the app’s label, namespace, and tabs. Describe information for a tab includes the sObject associated with the tab, tab icons and colors.
List<Schema.DescribeTabSetResult> tabSetDesc = Schema.describeTabs();
-
Write dynamic SOQL queries, dynamic SOSL queries and dynamic DML
-
Understanding Apex Describe Information
-
Using Field Tokens
To access the token for a field, use one of the following methods:
a. Access the static member variable name of an sObject static type, for example, Account.Name.
b. Call the getSObjectField method on a field describe result. -
Understanding Describe Information Permissions
a. With native code (i.e. classes and triggers that are not included in a package), you can generate a map of all the sObjects for your organization, regardless of the current user's permission.
b. If you execute describe calls in an anonymous block, user permissions are taken into account. As a result, not all sObjects and fields can be looked up if access is restricted for the running user.
c. Dynamic Apex, contained in managed packages created by Salesforce ISV partners that are installed from AppExchange, have restricted access to any sObject outside the managed package. Partners can set the API Access value within the package to grant access to standard sObjects not included as part of the managed package. While Partners can request access to standard objects, custom objects are not included as part of the managed package and can never be referenced or accessed by dynamic Apex that is packaged. -
Describing sObjects Using Schema Method
// sObject types to describe String[] types = new String[]{'Account','Merchandise__c'};
// Make the describe call Schema.DescribeSobjectResult[] results = Schema.describeSObjects(types);
System.debug('Got describe information for ' + results.size() + ' sObjects.');
// For each returned result, get some info
for(Schema.DescribeSobjectResult res : results) { System.debug('sObject Label: ' + res.getLabel()); System.debug('Number of fields: ' + res.fields.getMap().size()); System.debug(res.isCustom() ? 'This is a custom object.' : 'This is a standard object.'); // Get child relationships Schema.ChildRelationship[] rels = res.getChildRelationships(); if (rels.size() > 0) { System.debug(res.getName() + ' has ' + rels.size() + ' child relationships.'); } }
-
Describing Tabs Using Schema Methods
-
Accessing All sObjects
Use the Schema getGlobalDescribe method to return a map that represents the relationship between all sObject names (keys) to sObject tokens (values).
For example:
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Note:
a. It is dynamic, that is, it is generated at runtime on the sObjects currently available for the organization, based on permissions.
b. The sObject names are case insensitive.
c. The keys are prefixed with the namespace, if any.*
d. The keys reflect whether the sObject is a custom object. -
Accessing All Data Categories Associated with an sObject
Use the describeDataCategoryGroups and describeDataCategoryGroupStructures methods to return the categories associated with a specific object:
a. Return all the category groups associated with the objects of your choice using describeDataCategoryGroups(sObjectNames).
b. From the returned map, get the category group name and sObject name you want to further interrogate using DescribeDataCategoryGroupResult Class
c. Specify the category group and associated object, then retrieve the categories available to this object using describeDataCategoryGroupStructures. -
Dynamic SOQL
a. Return a single sObject when the query returns a single record:
sObject s = Database.query(string_limit_1);
b.Return a list of sObjects when the query returns more than a single record:
List<sObject> sobjList = Database.query(string);
c. Unlike inline SOQL, dynamic SOQL can’t use bind variable fields in the query string (e.g. :myVariable.field1__c). Instead you can resolve the variable field into a string and use the string in your dynamic SOQL query.
d. To prevent SOQL injection, use the escapeSingleQuotes method. This method adds the escape character () to all single quotation marks in a string that is passed in from a user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands. -
Dynamic SOSL
a. create a dynamic SOSL query at run time, use the search:
List<List<sObject>> myQuery = search.query(SOSL_search_string);
b. The following example exercises a simple SOSL query string.
String searchquery='FIND\'Edge*\'IN ALL FIELDS RETURNING Account(id,name),Contact, Lead'; List<List<SObject>>searchList=search.query(searchquery);
c. To provide more context for records in search results, use the SOSL WITH SNIPPET clause.
Search.SearchResults searchResults = Search.find('FIND \'test\' IN ALL FIELDS RETURNING KnowledgeArticleVersion(id, title WHERE PublishStatus = \'Online\' AND Language = \'en_US\') WITH SNIPPET (target_length=120)');
List<Search.SearchResult> articleList = searchResults.get('KnowledgeArticleVersion');
for (Search.SearchResult searchResult : articleList) { KnowledgeArticleVersion article = (KnowledgeArticleVersion) searchResult.getSObject(); System.debug(article.Title); System.debug(searchResult.getSnippet()); }
Search snippets and highlights are generated from the following field types: Email, Text, Text Area, Text Area (Long), Text Area (Rich).
d. To prevent SOSL injection, use the escapeSingleQuotes method. This method adds the escape character () to all single quotation marks in a string that is passed in from a user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands. -
Dynamic DML
a. To create a new sObject of a given type, use the newSObject method on an sObject token. Note that the token must be cast into a concrete sObject type (such as Account). -
Enforcing Object and Field Permissions
By default, the current user's permissions, field-level security, and sharing rules aren’t taken into account during Apex code execution except code executed in executeAnonymous call and Chatter in Apex.
You can enforce these permissions in your code by explicitly calling the sObject describe result methods (Schema.DescribeSObjectResult) and the field describe result methods (Schema.DescribeFieldResult) that check the current user's access permission levels. In this way, you can verify if the current user has the necessary permissions, and only if he or she has sufficient permissions, you can then perform a specific DML operation or a query.
If sharing rules are defined in Salesforce, you can enforce them at the class level by declaring the class with the with sharing keyword.
Use the with sharing or without sharing keywords on a class to specify whether or not to enforce sharing rules.
The with sharing keyword allows you to specify that the sharing rules for the current user be taken into account for a class. -
Enforcing CRUD and FLS
When rendering VisualForce pages, the platform will automatically enforce CRUD and FLS when the developer references SObjects and SObject fields directly in the VisualForce page.
VisualForce will also remove fields for which users do not have FLS visibility when rendering edit pages. Additionally, all apex:inputField tags will be rendered as read-only elements for fields that are set to read-only through FLS. Input tags such as apex:inputText and apex:inputTextArea will also automatically enforce FLS restrictions.
The field describe calls available in Apex are also available in VisualForce through the $ObjectType element. While enforcement in Apex controllers is preferred for scalability and general robustness reasons, there are situations where manual enforcement in VisualForce is useful.
Since Apex web services do not have a VisualForce binding layer, all CRUD and FLS enforcement must be done within the Apex code.
Describe the capabilities and use cases for formula fields.
- Remember cross object formula always works from child to parent meaning you can create formula on child and reference fields from it's parent!
- And if a parent has to refer to children then it might be a roll-up summary field if there is a master-detail relation or otherwise a trigger for more complex logic.
- Workflow rules can update fields on the record itself or it's related parents for an update. Never children. Process Builder can update children!
- Formula Field Data Types: Checkbox, Currency (18 digits with a currency sign), Date (not for custom summary formula in reports),Date/Time(not for custom summary formula in reports), Number, Percentage, Text(not for custom summary formula in reports)
- Cross-object formulas that reference currency fields convert the value to the currency of the record that contains the formula. If the referenced currency field is from a custom setting, the field value isn’t converted to the record’s currency.
- Salesforce allows a maximum of 10 unique relationships per object in cross-object formulas. The limit is cumulative across all formula fields, rules, and lookup filters. For example, if two different formulas on opportunities reference two different fields of an associated account, only one unique relationship exists (from opportunities to accounts).
- You can’t reference cross-object formulas in roll-up summary fields.
- In cross-object formulas, you can’t reference 9. merge fields for objects related to activities. For example, merge fields for contacts and accounts aren’t available in task and event formulas.
- Some objects support different object types for the Owner field, such as a User, Queue, or Calendar. On objects that support this behavior, when creating a cross-object formula using Owner, you must be explicit about the owner type you’re referencing.
- The value of the Profile.Name merge field differs depending on the context of the cross-object formula field that references it. On detail pages, the value is the profile name, as expected. In list views and reports, the value is the internal value of the associated profile instead. If you use Profile.Name in a formula, use it within an OR function to ensure that the formula always returns the intended result. For example:
IF (OR (LastModifiedBy.Profile.Name = "Standard User", LastModifiedBy.Profile.Name = "PT2"), "Standard", "Not Standard")
Describe the capabilities and use cases for roll-up summary fields.
- Create roll-up summary fields on:
- Any custom object that is on the master side of a master-detail relationship
- Any standard object that is on the master side of a master-detail relationship with a custom object
- Opportunities using the values of opportunity products related to the opportunity
- Accounts using the values of related opportunities
- Campaigns using campaign member status or the values of campaign member custom fields
- The types of fields you can calculate in a roll-up summary field depend on the type of calculation.
- Number, currency, and percent fields are available when you select SUM as the roll-up type.
- Number, currency, percent, date, and date/time fields are available when you select MIN or MAX as the roll-up type.
- Administration
- Make sure that the filter for your roll-up summary doesn't encounter a formula field that results in “#Error!”. 否则,出错的记录不会被roll-up到master record
- When you delete a child record on a roll-up Summary field, Salesforce doesn’t recalculate the value of the field. Select the Force a mass recalculation on this field option on the **edit page **of the roll-up summary field to manually recalculate the value.
- You can’t use long text area, multi-select picklist, Description fields, system fields like Last Activity, cross-object formula fields, and lookup fields in the field column of roll-up summary filters.
- Auto number fields are not available as the field to aggregate in a roll-up summary field.
- After you have created a roll-up summary field on an object, you cannot convert the object's master-detail relationship into a lookup relationship.
- Roll-up summary fields are not available for mapping lead fields of converted leads
- Management
- If a roll-up summary field doesn’t contain cross-object field references or functions that derive values on the fly, such as NOW or TODAY, it can calculate the values of formula fields.
- Changes to the value of a roll-up summary field can trigger assignment rules to run. If a roll-up summary field is part of the criteria in an assignment rule, the field’s new value is used to evaluate whether to reassign the record.
- A roll-up summary field can trigger workflow rules and field validations. However, workflow rules and field validations do not fire when the following changes cause a mass recalculation of roll-up summary values:
- Changing the roll-up summary definition (such as the object, function, or field being aggregated)
- Changing the expression of a formula field referenced in a roll-up summary field
- Replacing picklist values for picklist fields referenced in the roll-up summary filter
- Changing picklist record type definitions
- Changing currency conversion rates
- Changing price book entries
- Because roll-up summary fields are not displayed on edit pages, you can use them in validation rules but not as the error location for your validation.
Describe the capabilities of the declarative process automation features.
- Use Case
Use Case | Lightning Flow Functionality |
---|---|
Create a guided tutorial or wizard with screens. | Cloud Flow Designer includes several out-of-the-box screen fields, like text boxes, radio buttons, and a file-upload component. If you need more than what’s offered, add custom Lightning components to your screens. |
Set up automated tasks and processes. | Declaratively configure logic and actions for your business process with either Process Builder or Cloud Flow Designer. If needed, you can build custom Apex code to fill any functional gaps. |
Connect to external systems. | Communicate changes between your Salesforce org and your external systems with platform events. Process Builder and Cloud Flow Designer let you respond to and send platform event messages. In addition, Cloud Flow Designer can retrieve data from third-party systems with External Services. |
Add automation to your pages and apps. | Make sure your behind-the-scenes processes start when the right thing happens, whether that’s when records change or when users click a particular button. Once you build guided visual experiences, add them to Lightning pages, Community pages, the utility bar in your Lightning apps, and more. |
Reuse what you build. | In Cloud Flow Designer, any flow can be used as a subflow. In Process Builder, create an invocable process to reuse that process’s logic or actions in other business processes. |
- Sample scenarios
Scenarios | Tools | What you build |
---|---|---|
Guide a community member through requesting a new credit card with a step-by-step wizard. | Cloud Flow Designer | Flow |
A sales rep clicks a button on an opportunity, which launches a discount calculator. | Cloud Flow Designer | Flow |
When an account is updated, update all the contacts related to that account. | Process Builder | Process |
When an opportunity stage is updated, update a custom checkbox field. | Process Builder | Process |
Create a task when a platform event occurs. | Process Builder | Process |
Update a lead record in Salesforce after a certain amount of time passes, or when a specified time is reached. | Process Builder | Process |
When an opportunity closes, automatically create a renewal opportunity. | Process Builder and Cloud Flow Designer | Process and flow |
Route an employee’s time-off request to a manager for approval. | Approvals | Approval process |
Describe when to use declarative automation features vs. Apex classes and triggers.
-
Use Apex if you want to:
- Create Web services.
- Create email services.
- Perform complex validation over multiple objects.
- Create complex business processes that are not supported by workflow.
- Create custom transactional logic (logic that occurs over the entire transaction, not just with a single record or object).
- Attach custom logic to another operation, such as saving a record, so that it occurs whenever the operation is executed, regardless of whether it originates in the user interface, a Visualforce page, or from SOAP API.
-
Visualforce consists of a tag-based markup language that gives developers a more powerful way of building applications and customizing the Salesforce user interface. With Visualforce you can:
- Build wizards and other multistep processes.
- Create your own custom flow control through an application.
- Define navigation patterns and data-specific rules for optimal, efficient application interaction.
-
Use standard SOAP API calls if you want to add functionality to a composite application that processes only one type of record at a time and does not require any transactional control (such as setting a Savepoint or rolling back changes).
Describe how to declare variables and constants in Apex and how to assign values using expressions.
- Apex Data Types:
- A primitive, such as an Integer, Double, Long, Date, Datetime, String, ID, or Boolean (see Primitive Data Types)
- An sObject, either as a generic sObject or as a specific sObject, such as an Account, Contact, or MyCustomObject__c (see sObject Types in Chapter 4.)
- A collection, including:
- A typed list of values, also known as an enum (see Enums)
- Objects created from user-defined Apex classes (see Classes, Objects, and Interfaces)
- Objects created from system supplied Apex classes
- Null (for the Null constant, which can be assigned to any variable)
Describe the primitive and complex Apex data types and when to use them.
Describe how to use and apply Apex control flow statements.
- If-Else
- Loops
- Do-While Loops:
do { code_block} while (condition);
- While Loops:
while(condition){code_block)
- For Loops
- Traditional:
for(init_stmt; exit_condition; increment_stmt) {code_block}
- List/Set Iteration for loop:
for(variable: list_or_set) {code_block}
- SOQL for loop:
for (variable: [soql_query]) {code_block}
orfor(variable_list: [soql_query]{code_block}
- Note that queries including an aggregate function don't support queryMore. A run-time exception occurs if you use a query containing an aggregate function that returns more than 2,000 rows in a for loop.
-
SOQL for loops can process records one at a time using a single sObject variable, or in batches of 200 sObjects at a time using an sObject list:
- The single sObject format executes the for loop's <code_block> once per sObject record. Consequently, it is easy to understand and use, but is grossly inefficient if you want to use data manipulation language (DML) statements within the for loop body. Each DML statement ends up processing only one sObject at a time.
- The sObject list format executes the for loop's <code_block> once per list of 200 sObjects. Consequently, it is a little more difficult to understand and use, but is the optimal choice if you need to use DML statements within the for loop body. Each DML statement can bulk process a list of sObjects at a time.
- DML statements can only process up to 10,000 records at a time, and sObject list for loops process records in batches of 200. Consequently, if you are inserting, updating, or deleting more than one record per returned record in an sObject list for loop, it is possible to encounter runtime limit errors. See Execution Governors and Limits.
- You might get a QueryException in a SOQL for loop with the message Aggregate query has too many rows for direct assignment, use FOR loop. This exception is sometimes thrown when accessing a large set of child records (200 or more) of a retrieved sObject inside the loop, or when getting the size of such a record set. For example, the query in the following SOQL for loop retrieves child contacts for a particular account. If this account contains more than 200 child contacts, for loop cause an exception. To avoid getting this exception, use a for loop to iterate over the child records.
- Traditional:
- Do-While Loops:
Describe how to write and when to use Apex classes and interfaces.
Apex Class
In Apex, you can define top-level classes (also called outer classes) as well as inner classes, that is, a class defined within another class. You can only have inner classes one level deep.
To define a class, specify the following:
1. Access modifiers: You must use one of the access modifiers (such as public or global) in the declaration of a top-level class. You do not have to use an access modifier in the declaration of an inner class.
2. Optional definition modifiers (such as virtual, abstract, and so on)
3. Required: The keyword class followed by the name of the class
4. Optional extensions and/or implementations
Syntax:
private | public | global
[virtual | abstract | with sharing | without sharing]
class*** ClassName*** [implements InterfaceNameList] [extends ClassName]
{
// The body of the class
}
- private: this class is only known by this section of code, default access for inner classes (can only used by inner class)
- public: this class is visible in your application or namespace
- global: this class is known by all Apex code everywhere
- all classes that contain method defined with the webService keyword must be declared as global
- if a method or inner class is declared as global, the outer, top-level class must as be defined as global
- The with sharing and without sharing keywords specify the sharing mode for this class.
- The virtual definition modifier declares that this class allows extension and overrides. You cannot override a method with the override keyword unless the class has been defined as virtual.
The abstract definition modifier declares that this class contains abstract methods, that is, methods that only have their signature declared and no body defined.
Notes:
- You cannot add an abstract method to a global class after the class has been uploaded in a Managed - Released package version.
- If the class in the Managed - Released package is virtual, the method that you can add to it must also be virtual and must have an implementation.
- You cannot override a public or protected virtual method of a global class of an installed managed package.
- A class can implement multiple interfaces, but only extend one existing class. This restriction means that Apex does not support multiple inheritance. The interface names in the list are separated by commas.
- In addition to classes, Apex provides triggers, similar to database triggers. A trigger is Apex code that executes before or after database operations. See Triggers.
- In Apex, all primitive data type arguments, such as Integer or String, are passed into methods by value. This means that any changes to the arguments exist only within the scope of the method. When the method returns, the changes to the arguments are lost.
- This example shows how a List argument is passed by value into another method and can be modified. It also shows that the List argument can’t be modified to point to another List object.
- In Apex, you can have static methods, variables, and initialization code. However, Apex classes can’t be static. You can also have instance methods, member variables, and initialization code, which have no modifier, and local variables.
Apex Interface
Describe how to use basic SOSL, SOQL, and DML statements when working with objects in Apex.
SOSL Queries
Salesforce Object Search Language (SOSL) is a Salesforce search language that is used to perform text searches in records. Use SOSL to search fields across multiple standard and custom object records in Salesforce.
When SOSL is embedded in Apex, it is referred to as inline SOSL.
SOQL and SOSL are two separate languages with different syntax. Each language has a distinct use case:
- Use SOQL to retrieve records for a single object.
- Use SOSL to search fields across multiple objects. SOSL queries can search most text fields on an object.
- SOQL statements evaluate to a list of sObjects, a single sObject, or an Integer for count method queries.
Syntax:
FIND 'SearchQuery' [IN SearchGroup] [RETURNING ObjectsAndFields]
- SearchQuery is the text to search for (a single word or a phrase). Search terms can be grouped with logical operators (AND, OR) and parentheses. Also, search terms can include wildcard characters (*, ?). The * wildcard matches zero or more characters at the middle or end of the search term. The ? wildcard matches only one character at the middle or end of the search term.
- Text searches are case-insensitive.
- SearchGroup is optional. It is the scope of the fields to search. If not specified, the default search scope is all fields. SearchGroup can take one of the following values.
- ALL FIELDS
- NAME FIELDS
- EMAIL FIELDS
- PHONE FIELDS
- SIDEBAR FIELDS
- ObjectsAndFields is optional. It is the information to return in the search result—a list of one or more sObjects and, within each sObject, list of one or more fields, with optional values to filter against. If not specified, the search results contain the IDs of all objects found.
SOQL Queries
To include SOQL queries within your Apex code, wrap the SOQL statement within square brackets and assign the return value to an array of sObjects.
Notes:
- Unlike other SQL languages, you can’t specify * for all fields. You must specify every field you want to get explicitly.
- You may want to specify the Id field also when running a query in the Query Editor as the ID field won’t be displayed unless specified.
- The default sort order is in alphabetical order, specified as ASC.
- SOQL statements in Apex can reference Apex code variables and expressions if they are preceded by a colon (:). The use of a local variable within a SOQL statement is called a bind.
-
Querying Related Records:
- To get child records related to a parent record, add an inner query for the child records. The FROM clause of the inner query runs against the relationship name, rather than a Salesforce object name.
- You can traverse a relationship from a child object (contact) to a field on its parent (Account.Name) by using dot notation.
DML Statements vs. Database Class Methods
One difference between the two options is that by using the Database class method, you can specify whether or not to allow for partial record processing if errors are encountered. You can do so by passing an additional second Boolean parameter. If you specify false (NOT DEFAULT VALUE) for this parameter and if a record fails, the remainder of DML operations can still succeed.
The following helps you decide when you want to use DML statements or Database class methods.
- Use DML statements if you want any error that occurs during bulk DML processing to be thrown as an Apex exception that immediately interrupts control flow (by using <try. . .catch blocks). This behavior is similar to the way exceptions are handled in most database procedural languages.
- Use Database class methods if you want to allow partial success of a bulk DML operation—if a record fails, the remainder of the DML operation can still succeed. Your application can then inspect the rejected records and possibly retry the operation. When using this form, you can write code that never throws DML exception errors. Instead, your code can use the appropriate results array to judge success or failure. Note that Database methods also include a syntax that supports thrown exceptions, similar to DML statements.
The convertLead operation is only available as a Database class method, not as a DML statement.
The Database class also provides methods not available as DML statements, such as methods transaction control and rollback, emptying the Recycle Bin, and methods related to SOQL queries.
Describe the basic patterns used in triggers and classes to process data efficiently.
- Use bulkify and no DML/SOQL within for loop
Best Practices for Designing Bulk Programs
The following are the best practices for this design pattern:
- Minimize the number of data manipulation language (DML) operations by adding records to collections and performing DML operations against these collections.
- Minimize the number of SOQL statements by preprocessing records and generating sets, which can be placed in single SOQL statement used with the IN clause.
Example:
Trigger MileageTrigger on Mileage__c (before insert, before update) {
Set<ID> ids = Trigger.newMap.keySet();
List<User> c = [SELECT Id FROM user WHERE mileageid__c in :ids];
}
Trigger Frameworks and Apex Trigger Best Practices
- One Trigger Per Object and let it handle all of the contexts that you need
- Logic-less Triggers: the role of the Trigger is just to delegate the logic responsibilities to some other handler class
- Context-Specific Handler Methods (e.g. handlerAfterInsert, handlerAfterUpdate, etc.)
Describe when to use and how to write triggers.
-
Syntax:
trigger TriggerName on ObjectName (trigger_events) { code_block }
- There are two types of triggers:
- Before triggers are used to update or validate record values before they’re saved to the database.
- After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records. The records that fire the after trigger are read-only.
- Calling addError() in a trigger causes the entire set of operations to roll back, except when bulk DML is called with partial success.
- If a DML statement in Apex spawned the trigger, any error rolls back the entire operation. However, the runtime engine still processes every record in the operation to compile a comprehensive list of errors.
- If a bulk DML call in the Lightning Platform API spawned the trigger, the runtime engine sets the bad records aside*. The runtime engine then attempts a partial save of the records that did not generate errors.
- Apex calls to external Web services are referred to as callouts. When making a callout from a trigger, call a class method that executes asynchronously. Such a method is called a future method and is annotated with
@future(callout=true)
. - Be aware of the following considerations for trigger context variables:
- trigger.new and trigger.old cannot be used in Apex DML operations.
- You can use an object to change its own field values using trigger.new, but only in before triggers.
- In all after triggers, trigger.new is not saved, so a runtime exception is thrown.
- trigger.old is always read-only.
- You cannot delete trigger.new.
Describe the implications of governor limits on Apex transactions.
Remember in a single transaction you can retrieve 50,000 records via SOQL, update 10,000 records, execute 100 SOQL calls and 150 DML statements max that will cover majority around limits. The question will be scenario based and from code sample you will have to figure out whether whole transaction gets committed or partial or nothing. Count through number of times any DML or SOQL being executed and number of records being executed correctly.
- SOQL:查询5万条,更新1万条,执行同步100次异步200次
- SOSL:查询20次,2000条
- DML:执行150次,处理1万条
- Database.getQueryLocator: 查询1万条
- Callout 一百次,每次timeout最多120秒
- future annotation 50次
- System.enqueueJob 50次
- sendEmail methods 10次
- push notification:执行10次,每次推送2000人
- namespace 10个
Describe the relationship between Apex transactions, the save order of execution, and the potential for recursion and/or cascading.
Apex Transaction
An Apex transaction represents a set of operations that are executed as a single unit. Transactions are useful when several operations are related, and either all or none of the operations should be committed.
Triggers and Order of Execution
When you save a record with an insert, update, or upsert statement, Salesforce (Server side) performs the following events in order:
-
Loads the original record from the database or initializes the record for an upsert statement.
-
Loads the new record field values from the request and overwrites the old values.
-
If the request came from a standard UI edit page, Salesforce runs system validation to check the record for:
- Compliance with layout-specific rules
- Required values at the layout level and field-definition level
- Valid field formats
- Maximum field length
-
When the request comes from other sources, such as an Apex application or a SOAP API call, Salesforce validates only the foreign keys. Prior to executing a trigger, Salesforce verifies that any custom foreign keys do not refer to the object itself.
-
Salesforce runs user-defined validation rules if multiline items were created, such as quote line items and opportunity line items.
-
-
Executes all before triggers.
-
Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any 8user-defined validation rules*. The only system validation that Salesforce doesn't run a second time (when the request comes from a standard UI edit page) is the enforcement of layout-specific rules.
-
Executes duplicate rules. If the duplicate rule identifies the record as a duplicate and uses the block action, the record is not saved and no further steps, such as after triggers and workflow rules, are taken.
-
Saves the record to the database, but doesn't commit yet.
-
Executes all after triggers.
-
Executes assignment rules.
-
Executes auto-response rules.
-
Executes workflow rules.
-
If there are workflow field updates, updates the record again.
-
If the record was updated with workflow field updates, fires before update triggers and after update triggers one more time (and only one more time), in addition to standard validations. Custom validation rules, duplicate rules, and escalation rules are not run again.
-
Executes processes.
If there are workflow flow triggers, executes the flows.
The pilot program for flow trigger workflow actions is closed. If you've already enabled the pilot in your org, you can continue to create and edit flow trigger workflow actions. If you didn't enable the pilot in your org, use the Flows action in Process Builder instead. -
Executes escalation rules.
-
Executes entitlement rules.
-
If the record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Parent record goes through save procedure.
-
If the parent record is updated, and a grandparent record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the grandparent record. Grandparent record goes through save procedure.
-
Executes Criteria Based Sharing evaluation.
-
Commits all DML operations to the database.
-
Executes post-commit logic, such as sending email
Describe how to implement exception handling in Apex.
Exception | Description |
---|---|
AsyncException | Any problem with an asynchronous operation, such as failing to enqueue an asynchronous call. |
CalloutException | Any problem with a Web service operation, such as failing to make a callout to an external system. |
DmlException | Any problem with a DML statement, such as an insert statement missing a required field on a record. |
EmailException | Any problem with email, such as failure to deliver. For more information, see Outbound Email. |
ExternalObjectException | Any problem with external object records, such as connection timeouts during attempts to access the data that’s stored on external systems. |
InvalidParameterValueException | An invalid parameter was supplied for a method or any problem with a URL used with Visualforce pages. For more information on Visualforce, see the Visualforce Developer's Guide. |
LimitException | A governor limit has been exceeded. This exception can’t be caught. |
JSONException | Any problem with JSON serialization and deserialization operations. For more information, see the methods of System.JSON, System.JSONParser, and System.JSONGenerator. |
ListException | Any problem with a list, such as attempting to access an index that is out of bounds. |
MathException> | Any problem with a mathematical operation, such as dividing by zero. |
NoAccessException | Any problem with unauthorized access, such as trying to access an sObject that the current user does not have access to. This is generally used with Visualforce pages. For more information on Visualforce, see the Visualforce Developer's Guide. |
<NoDataFoundException | Any problem with data that does not exist, such as trying to access an sObject that has been deleted. This is generally used with Visualforce pages. For more information on Visualforce, see the Visualforce Developer's Guide. |
NoSuchElementException | This exception is thrown if you try to access items that are outside the bounds of a list. This exception is used by the Iterator next method. For example, if iterator.hasNext() == false and you call iterator.next(), this exception is thrown. This exception is also used by the Apex Flex Queue methods and is thrown if you attempt to access a job at an invalid position in the flex queue. |
NullPointerException | Any problem with dereferencing null, such as in the following code: String s; s.toLowerCase(); ``// Since s is null, this call causes // a NullPointerException
|
QueryException | Any problem with SOQL queries, such as assigning a query that returns no records or more than one record to a singleton sObject variable. |
RequiredFeatureMissing | A Chatter feature is required for code that has been deployed to an organization that does not have Chatter enabled. |
SearchException | Any problem with SOSL queries executed with SOAP API search() call, for example, when the searchString parameter contains less than two characters. For more information, see the SOAP API Developer Guide. |
SecurityException | Any problem with static methods in the Crypto utility class. For more information, see Crypto Class. |
SerializationException | Any problem with the serialization of data. This is generally used with Visualforce pages. For more information on Visualforce, see the Visualforce Developer's Guide. |
SObjectException | Any problem with sObject records, such as attempting to change a field in an update statement that can only be changed during insert. |
StringException | Any problem with Strings, such as a String that is exceeding your heap size. |
TypeException | Any problem with type conversions, such as attempting to convert the String 'a' to an Integer using the valueOf method. |
VisualforceException | Any problem with a Visualforce page. For more information on Visualforce, see the Visualforce Developer's Guide. |
XmlException | Any problem with the XmlStream classes, such as failing to read or write XML. |
Describe how to write Visualforce controllers.
Standard List Controller
The standard list controller allows you to create Visualforce pages that can display or act on a set of records.
- Available in Account, Asset, Campaign, Case, Contact, Contract, Idea, Lead, Opportunity, Order, Product2, Solution, User, Custom objects
- The recordSetVar attribute not only indicates that the page uses a list controller, it sets the variable name of the record collection. This variable can be used to access data in the record collection.
- As with queries in the Lightning Platform API, you can use expression language syntax to retrieve data from related records. As with standard controllers, you can traverse up to five levels of child-to-parent relationships and one level of parent-to-child relationships.
- When using a standard list controller, the returned records sort on the first column of data, as defined by the current view, even if that column is not rendered.
- Standard List Controller Actions:
-
Available in the following tags: <apex:commandButton>, <apex:commandLink>, <apex:actionPoller>, <apex:actionSupport>, <apex:actionFunction>, <apex:page>
-
Actions summary:
Action Description save Inserts new records or updates existing records that have been changed. After this operation is finished, the save action returns the user to the original page, if known, or the home page. quicksave Inserts new records or updates existing records that have been changed. Unlike the save action, quicksave does not redirect the user to another page. list Returns a PageReference object of the standard list page, based on the most recently used list filter for that object when the filterId is not specified by the user. cancel Aborts an edit operation. After this operation is finished, the cancel action returns the user to the page where the user originally invoked the edit. first Displays the first page of records in the set. last Displays the last page of records in the set. next Displays the next page of records in the set. previous Displays the previous page of records in the set.
-
- Pagination: By default, a list controller returns 20 records on the page. To control the number of records displayed on each page, use a controller extension to set the pageSize. For information on controller extensions, see Building a Controller Extension. When you use pagination, an exception is thrown when there are modified rows in the collection.
- Listview: This page is associated with the standard account controller and the <apex:selectlist> component is populated by {!listviewoptions}, which evaluates to the list views the user can see. When the user chooses a value from the drop-down list, it is bound to the filterId property for the controller. When the filterId is changed, the records available to the page changes, so, when the <apex:datalist> is updated, that value is used to update the list of records available to the page.
<apex:page standardController="Account" recordSetvar="accounts">
<apex:pageBlock title="Viewing Accounts">
<apex:form id="theForm">
<apex:panelGrid columns="2">
<apex:outputLabel value="View:"/>
<apex:selectList value="{!filterId}" size="1">
<apex:actionSupport event="onchange" rerender="list"/>
<apex:selectOptions value="{!listviewoptions}"/>
</apex:selectList>
</apex:panelGrid>
<apex:pageBlockSection >
<apex:dataList var="a" value="{!accounts}" id="list">
{!a.name}
</apex:dataList>
</apex:pageBlockSection>
</apex:form>
</apex:pageBlock>
</apex:page>
Describe when and how to use standard Visualforce controllers vs. Apex custom controllers and controller extensions.
Standard Controller
- Provide the record ID for a record to the standard controller by adding it as a parameter in the request URL.
Custom Controller
- Custom controllers contain custom logic and data manipulation that can be used by a Visualforce page.
- The getContacts() method is called a getter method, and it’s a general pattern, where {! someExpression } in your Visualforce markup automatically connects to a method named getSomeExpression() in your controller. This is the simplest way for your page to get access to the data it needs to display.
Controller Externsion
A controller extension is any Apex class containing a constructor that takes a single argument of type ApexPages.StandardController or CustomControllerName, where CustomControllerName is the name of a custom controller you want to extend.
The extension is associated with the page using the extensions attribute of the <apex:page> component.
Multiple controller extensions can be defined for a single page through a comma-separated list. This allows for overrides of methods with the same name. Overrides are defined by whichever methods are defined in the “leftmost” extension, or, the extension that is first in the comma-separated list.
Describe the programmatic techniques to prevent security vulnerabilities in Apex and Visualforce.
Enforcing Sharing Rule
- Apex generally runs in system context; that is, the current user's permissions, field-level security, and sharing rules aren’t taken into account during code execution.The only exceptions to this rule are Apex code that is executed with the executeAnonymous call and Chatter in Apex. executeAnonymous always executes using the full permissions of the current user.
- Enforcing sharing rules by using the with sharing keyword doesn’t enforce the user's permissions and field-level security. Apex code always has access to all fields and objects in an organization, ensuring that code won’t fail to run because of hidden fields or objects for a user.
Enforcing Object and Field Permissions
Although Apex doesn't enforce object-level and field-level permissions by default, you can enforce these permissions in your code by explicitly calling the sObject describe result methods (of Schema.DescribeSObjectResult) and the **field describe **result methods (of Schema.DescribeFieldResult) that check the current user's access permission levels. In this way, you can verify if the current user has the necessary permissions, and only if he or she has sufficient permissions, you can then perform a specific DML operation or a query.
Class Security
You can specify which users can execute methods in a particular top-level class based on their user profile or permission sets. You can only set security on Apex classes, not on triggers.
Sharing
- Force.com Managed Sharing: Record OwnSharing Rules, Role Hierachy, Force.com. All implicit sharing added by Force.com managed sharing cannot be altered directly using the Salesforce user interface, SOAP API, or Apex.
- User Managed Sharing, also known as Manual Sharing: User managed sharing is removed when the record owner changes or when the access granted in the sharing does not grant additional access beyond the object's organization-wide sharing default access level.
- Apex Managed Sharing provides developers with the ability to support an application’s particular sharing requirements programmatically through Apex or the SOAP API. This type of sharing is similar to Force.com managed sharing. Only users with “Modify All Data” permission can add or change Apex managed sharing on a record. Apex managed sharing is maintained across record owner changes.
- Apex sharing reasons and Apex managed sharing recalculation are only available for custom objects.
- In the Salesforce user interface, the Reason field on a custom object specifies the type of sharing used for a record. This field is called rowCause in Apex or the API.
- Sharing a Record Using Apex
To access sharing programmatically, you must use the share object associated with the standard or custom object for which you want to share. For example, AccountShare is the sharing object for the Account object, ContactShare is the sharing object for the Contact object. In addition,
all custom object sharing objects are named as follows, where MyCustomObject is the name of the custom object: MyCustomObject__Share
Properties of Share Object
Describe how Apex impacts the ability to make declarative changes.
USER INTERFACE (10%)
Describe how to display Salesforce data using a Visualforce page.
Describe the types of web content that can be incorporated into Visualforce pages.
Maps, Charts, flows, PDF renderer and custom content type.
Describe how to incorporate Visualforce pages into Lightning Platform applications.
- Display a Visualforce Page from a Tab
- Display a Visualforce Page within a Standard Page Layout
- Display a Visualforce Page by Overriding Standard Buttons or Links
- Display a Visualforce Page Using Custom Buttons or Links
- Display a Visualforce Page as the Target of a Link
Describe the benefits of the Lightning Component framework.
- Out-of-the-Box Component Set
- Performance
The component framework leverages a stateful client (using JavaScript) and a stateless server (using Apex). This structure allows the client to call the server only when absolutely necessary. With fewer calls to the server, your apps are more responsive and efficient. - Event-Driven Architecture
- Rapid Development
- Device-Aware and Cross-Browser Compatibility
Describe the resources that can be contained in a Lightning Component.
Component bundleTESTING (12%)
TestVisible Annotation
Use the TestVisible annotation to allow test methods to access private or protected members of another class outside the test class. These members include methods, member variables, and inner classes. This annotation enables a more permissive access level for running tests only. This annotation doesn’t change the visibility of members if accessed by non-test classes.
Describe the testing framework and requirements for deployment.
- Unit tests are class methods that verify whether a particular piece of code is working properly. Unit test methods take no arguments, commit no data to the database, send no emails, and are flagged with the testMethod keyword or the @isTest annotation in the method definition. Also, test methods must be defined in test classes, that is, classes annotated with @isTest.
- Classes defined as @isTest must be top-level classes and can't be interfaces or enums.
Unit Test Consideration
- tarting with Salesforce API 28.0, test methods can no longer reside in non-test classes and must be part of classes annotated with isTest.
- Test methods can’t be used to test Web service callouts. Instead, use mock callouts. See Test Web Service Callouts and Testing HTTP Callouts.
- You can’t send email messages from a test method.
- Since test methods don’t commit data created in the test, you don’t have to delete test data upon completion.
- If a test class contains a static member variable, and the variable’s value is changed in a testSetup or test method, the new value isn’t preserved. Other test methods in this class get the original value of the static member variable. This behavior also applies when the static member variable is defined in another class and accessed in test methods.
- For some sObjects that have fields with unique constraints, inserting duplicate sObject records results in an error. For example, inserting CollaborationGroup sObjects with the same names results in an error because CollaborationGroup records must have unique names.
- Tracked changes for a record (FeedTrackedChange records) in Chatter feeds aren't available when test methods modify the associated record. FeedTrackedChange records require the change to the parent record they're associated with to be committed to the database before they're created. Since test methods don't commit data, they don't result in the creation of FeedTrackedChange records. Similarly, field history tracking records (such as AccountHistory) can't be created in test methods because they require other sObject records to be committed first (for example, Account).
Describe how to write unit tests for triggers, controllers, and classes.
Text Apex Trigger
The test method contains the Test.startTest() and Test.stopTest() method pair, which delimits a block of code that gets a fresh set of governor limits. To isolate the data setup process’s limit usage, enclose the test call within the Test.startTest() and Test.stopTest() block. Also use this test block when testing asynchronous Apex.
Testing Custom Controllers and Controller Extensions
When writing unit tests for controller extension and custom controller classes, you can set query parameters that can then be used in the tests.
Using Limits, startTest, and stopTest
The startTest method marks the point in your test code when your test actually begins. Each test method is allowed to call this method only once. All of the code before this method should be used to initialize variables, populate data structures, and so on, allowing you to set up everything you need to run your test. Any code that executes after the call to startTest and before stopTest is assigned a new set of governor limits.
The stopTest method marks the point in your test code when your test ends. Use this method in conjunction with the startTest method. Each test method is allowed to call this method only once. Any code that executes after the stopTest method is assigned the original limits that were in effect before startTest was called. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously.
Describe when and how to use various sources of test data.
Isolation of Test Data from Organization Data in Unit Tests:
- Whenever possible, you should create test data for each test. You can disable this restriction by annotating your test class or test method with the IsTest(SeeAllData=true) annotation.
- If a test class is defined with the @isTest(SeeAllData=true) annotation, this annotation applies to all its test methods whether the test methods are defined with the @isTest annotation or the (deprecated) testMethod keyword.
- The @isTest(SeeAllData=true) annotation is used to open up data access when applied at the class or method level. However, if the containing class has been annotated with @isTest(SeeAllData=true), annotating a method with @isTest(SeeAllData=false) is ignored for that method. In this case, that method still has access to all the data in the organization. Annotating a method with @isTest(SeeAllData=true) overrides, for that method, an @isTest(SeeAllData=false) annotation on the class.
- If a test makes a Visualforce request, the executing test stays in test context but runs in a different thread, so test data isolation is no longer enforced. In this case, the test will be able to access all data in the organization after initiating the Visualforce request. However, if the Visualforce request performs a callback, such as a JavaScript remoting call, any data inserted by the callback won't be visible to the test.
Loading Test Data
Using the Test.loadData method, you can populate data in your test methods without having to write many lines of code.
Follow these steps:
- Add the data in a .csv file.
- Create a static resource for this file.
- Call Test.loadData within your test method and passing it the sObject type token and the static resource name.
Example:
List<sObject> ls = Test.loadData(Account.sObjectType, 'myResource');
You must create the static resource prior to calling this method. The static resource is a comma-delimited file ending with a .csv extension. The file contains field names and values for the test records. The first line of the file must contain the field names and subsequent lines are the field values.
Common test utility classes
Common test utility classes are public test classes that contain reusable code for test data creation.
Public test utility classes are defined with the isTest annotation, and as such, are excluded from the **organization code size limit
** and execute in test context. They can be called by test methods but not by non-test code.
The methods should be declared as public or global to be visible to other test classes.
Test Setup Methods
Use test setup methods (methods that are annotated with @testSetup) to create test records once and then access them in every test method in the test class.
By setting up records once for the class, you don’t need to re-create records for each test method. Also, because the rollback of records that are created during test setup happens at the end of the execution of the entire class, the number of records that are rolled back is reduced. As a result, system resources are used more efficiently compared to creating those records and having them rolled back for each test method.
If a test class contains a test setup method, the testing framework executes the test setup method first, before any test method in the class. Records that are created in a test setup method are available to all test methods in the test class and are rolled back at the end of test class execution. If a test method changes those records, such as record field updates or record deletions, those changes are rolled back after each test method finishes execution. The next executing test method gets access to the original unmodified state of those records.
Test Setup Consideration
Test setup methods are supported only with the default data isolation mode for a test class.If the test class or a test method has access to organization data by using the @isTest(SeeAllData=true) annotation, test setup methods aren’t supported in this class. Because data isolation for tests is available for API versions 24.0 and later, test setup methods are also available for those versions only.
You can have only one test setup method per test class.
If a fatal error occurs during the execution of a test setup method, such as an exception that’s caused by a DML operation or an assertion failure, the entire test class fails, and no further tests in the class are executed.
If a test setup method calls a non-test method of another class, no code coverage is calculated for the non-test method.
Describe how to execute one or multiple test classes.
All Apex tests that are started from the Salesforce user interface (including the Developer Console) run asynchronously and in parallel. Apex test classes are placed in the Apex job queue for execution. The maximum number of test classes that you can run per 24-hour period is the greater of 500 or 10 multiplied by the number of test classes in the org. For sandbox and Developer Edition organizations, this limit is higher and is the greater of 500 or 20 multiplied by the number of test classes in the org.
Notes:
- Apex tests that run as part of a deployment always run synchronously and serially.
- If you have Apex classes that are installed from a managed package, you must compile these classes first by clicking Compile all classes on the Apex Classes page so that they appear in the list.
Describe the differences between invoking Apex in execute anonymous vs. unit tests.
Unit test executes in system mode and any changes made to records are not visible out of its test execution context where with anonymous block any changes performed to data are visible after its execution is successful. Code written in anonymous block is not stored as metadata in salesforce org and user permissions are enforced during execution.
DEBUG AND DEPLOYMENT TOOLS (10%)
Describe how to monitor and access various types of debug logs.
Overview of Debug Logs
A debug log can record database operations, system processes, and errors that occur when executing a transaction or running unit tests. Debug logs can contain information about:
- Database changes
- HTTP callouts
- Apex errors
- Resources used by Apex
-
Automated workflow processes, such as:
- Workflow rules
- Assignment rules
- Approval processes
- Validation rules
Debug Logs limits
- Each debug log must be 2 MB or smaller. Debug logs that are larger than 2 MB are reduced in size by removing older log lines, such as log lines for earlier System.debug statements. The log lines can be removed from any location, not just the start of the debug log.
- Debug logs are retained for 7 days.
- If you generate more than 250 MB of debug logs in a 15-minute window, your trace flags are disabled. We send an email to the users who last modified the trace flags, informing them that they can re-enable the trace flag in 15 minutes.
Debug Log Components
- The header which contains the following information.
- The version of the API used during the transaction.
- The log category and level used to generate the log
- Execution Units
- Code Units
- Log Lines:
- Debug log filtering provides a mechanism for fine-tuning the log verbosity at the trigger and class level.
Debug Log Line Example
Event name: USER_DEBUG; Line number of the event in the code: 2; Logging Level: DEBUG; Logging message: Helllo world.
Checkpoints Tab
Checkpoints tab snapshotEach checkpoint in the list displays this information:
Column | Description |
---|---|
Namespace | The namespace of the package containing the checkpoint. |
Class | The Apex class containing the checkpoint. |
Line | The line number marked with the checkpoint. |
Time | The time the checkpoint was reached. |
Describe the capabilities and security implications of the Developer Console, Workbench, and Force.com IDE.
Change Set Considerations
You can move metadata only between the production org and its sandboxes. You can’t move changes between two production orgs or Developer Editions.
You can add components with a change set, but you can’t delete them. You must use another method to delete components, typically manually.
Because change sets are cloud-based, they’re not ideal when used with a source control system.
Ant Migration Tool Considerations
Requires a more developer-oriented skill set, with experience of Ant and scripting tools
Requires storing the username and password on disk, which some security policies don’t permit
Other deployment tool
Tool | Best For | Limitations |
---|---|---|
Force.com IDE Description: Plug-in to Eclipse used for both development and deployment |
Project-based development Deployment to any org Synchronizing changes Selecting only the components you need |
Some setup required Not always upgraded at the same time as other Salesforce products Repeatable deployments require re-selecting components, which can be time consuming and introduce errors |
Force.com Workbench Description: Lightweight web-based tool that uses your local file system |
Ad hoc queries Deploy or retrieve components with a package.xml file Metadata describes Lightweight data loads |
Not an officially supported product No project management features |
Force.com CLI Description: Command-line interface for Force.com APIs |
Scripted commands and automated tasks When your security policies dictate that passwords must not be stored on disk; forces interactive login |
Logging in can be difficult behind a firewall |
Describe the different processes for deploying metadata and business data.
Describe how the different environments are used in the development and deployment process.
Table 1. Sandbox Comparison
Developer | Developer Pro | Partial Copy | Full | |
---|---|---|---|---|
Refresh Interval | 1 day | 1 day | 5 days | 29 days |
Copies Data | No | No | Yes | Yes |
Size | 200 MB | 1 GB | 5 GB | Same as production |
Templates and Sampling | No & No | No & No | Yes & Yes | Yes & No |
Bundled Developer Sandboxes | N/A | 5 | 10 | 15 |