SALESFORCE CERTIFICATION
Certified Platform Developer Practice Exam
Exam Number: 3704 | Last updated 14-Apr-26 | 2354+ questions across 4 vendor-aligned objectives
The Certified Platform Developer credential validates your ability to write custom business logic using Apex, build Lightning Web Components, and work with Salesforce’s data model programmatically. It is aimed at developers who extend the platform beyond what declarative tools can accomplish.
The Process Automation and Logic domain weighs in at 30%, covering Apex triggers, classes, interfaces, Batch Apex, and Queueable Apex. With 25% of the exam, User Interface demands serious preparation, covering Lightning Web Components, Aura components, Visualforce basics, and event handling. Questions on developer fundamentals make up 23% of the test, covering multi-tenant architecture, MVC pattern, governor limits, and development lifecycle. Combined, these sections account for the lion’s share of the exam and reflect the skills employers value most.
The remaining sections balance the blueprint. With 22% of the exam, Testing, Debugging, and Deployment demands serious preparation, which spans test classes, debug logs, deployment tools, and Salesforce DX. While narrower in scope, questions in these domains test applied judgment that crosses objective boundaries.
Every answer links to the source. Each explanation below includes a hyperlink to the exact Salesforce documentation page the question was derived from. PowerKram is the only practice platform with source-verified explanations. Learn about our methodology →
899
practice exam users
95%
satisfied users
95.1%
passed the exam
5/5
quality rating
Test your Certified Platform Developer knowledge
10 of 2354+ questions
Question #1 - Streamline and scale Apex triggers, classes, and interfaces to eliminate repetitive manual work and enforce consistent business logic across teams
A developer is building an Apex trigger on the Opportunity object that needs to update the parent Account’s ‘Total Opportunity Amount’ field every time an Opportunity is inserted or updated.
Which trigger events and best practice pattern should the developer use?
A) An after insert trigger with a future method to update the Account asynchronously
B) An after insert and after update trigger that delegates logic to a handler class
C) A before insert trigger only, since before triggers can modify parent records
D) A before insert and before update trigger with direct DML inside the trigger body
Show solution
Correct answers: B – Explanation:
After triggers should be used when the operation requires DML on related records. Delegating logic to a handler class follows the single-trigger-per-object best practice. Before triggers cannot perform DML on related objects. Using a future method adds unnecessary complexity for a synchronous requirement. Source: Trailhead: Apex Triggers
Question #2 - Validate and troubleshoot test classes, debug logs, and deployment tools to catch issues before they reach production and maintain code quality across releases
A developer needs to write an Apex class that makes an HTTP callout to an external inventory system. During testing, the developer encounters an error stating that callouts are not allowed in test methods.
How should the developer handle this testing requirement?
A) Use Test.startTest() and Test.stopTest() to enable callouts in test context
B) Skip testing the callout method and test only the data processing logic
C) Create a mock class that implements the HttpCalloutMock interface and set it using Test.setMock()
D) Add the @IsTest(SeeAllData=true) annotation to the test class
Show solution
Correct answers: C – Explanation:
The HttpCalloutMock interface allows developers to create mock responses for HTTP callouts during testing. Using Test.setMock() registers the mock so that all callouts in the test context return the defined mock response. SeeAllData does not enable callouts. Skipping callout tests leaves code uncovered. Test.startTest/stopTest resets governor limits but does not enable real callouts. Source: Trailhead: Apex Integration
Question #3 - Build and polish Lightning Web Components, Aura components, and Visualforce basics to deliver intuitive, responsive interfaces that drive user adoption and productivity
A developer has created a Lightning Web Component that displays account details. The component needs to retrieve the Account record based on the record page it is placed on, without writing any Apex.
Which approach should the developer use?
A) Fetch the record using the REST API with a JavaScript fetch call
B) Use the Apex @AuraEnabled method with cacheable=true to query the Account
C) Import the getRecord wire adapter from lightning/uiRecordApi and use @api recordId
D) Use the lightning-record-form base component and bind it to the record ID
Show solution
Correct answers: C – Explanation:
The getRecord wire adapter from lightning/uiRecordApi allows an LWC to declaratively retrieve record data using the @api recordId property. No Apex is required. While lightning-record-form also works, getRecord provides more control. Apex methods and REST API calls are unnecessary when wire adapters are available. Source: Trailhead: LWC Basics
Question #4 - Streamline and scale Apex triggers, classes, and interfaces to eliminate repetitive manual work and enforce consistent business logic across teams
A developer is processing a batch of 10,000 Opportunity records in a Batch Apex class. The execute method needs to make an HTTP callout to an external pricing service for each batch of 200 records.
What must the developer do to enable callouts in the Batch Apex class?
A) Enable the ‘Allow Callouts’ checkbox in the Apex Jobs settings
B) Wrap the callout in a Queueable class and chain it from the execute method
C) Add the @future(callout=true) annotation to the execute method
D) Implement the Database.AllowsCallouts interface on the batch class
Show solution
Correct answers: D – Explanation:
The Database.AllowsCallouts interface must be implemented on the batch class to permit HTTP callouts within the execute method. The @future annotation cannot be used inside batch execute methods. There is no ‘Allow Callouts’ checkbox. While Queueable chaining is possible, it adds unnecessary complexity. Source: Trailhead: Asynchronous Apex
Question #5 - Validate and troubleshoot test classes, debug logs, and deployment tools to catch issues before they reach production and maintain code quality across releases
A developer is writing a test class for an Apex trigger that fires on Contact creation. The trigger relies on an existing Account record with a specific field value.
What is the correct approach?
A) Use @IsTest(SeeAllData=true) to access existing Account records in the org
B) Query for any Account record and use it in the test since test data is shared
C) Use Test.loadData() with a static resource containing a generic Account record
D) Create the required Account record within the test method using @TestSetup or inline setup
Show solution
Correct answers: D – Explanation:
Best practice is to create all test data within the test class, either in a @TestSetup method or inline. This ensures tests are self-contained and independent of org data. SeeAllData=true creates fragile tests. Test data is isolated by default. Test.loadData() works but is less maintainable for simple setups. Source: Trailhead: Apex Testing
Question #6 - Handle and manage multi-tenant architecture, MVC pattern, and governor limits to deliver reliable platform solutions that meet real-world business demands
A developer has an Apex trigger that works for single-record operations but fails when a data load inserts 500 Contact records at once, hitting the SOQL query limit.
What is the root cause and how should the developer fix it?
A) The developer should increase the SOQL query governor limit by requesting a limit increase
B) The trigger is not bulkified — SOQL queries are inside a for loop and should be moved outside using collections
C) The trigger should use @future methods to handle the records asynchronously
D) The batch size is too large and should be reduced to 50 records per batch
Show solution
Correct answers: B – Explanation:
Placing SOQL queries inside a loop causes one query per record, quickly exceeding the 100-query governor limit. The fix is to bulkify by collecting IDs first, executing a single query outside the loop, and processing with maps. Governor limits cannot be increased. Reducing batch size does not fix the code. Future methods have their own limits. Source: Trailhead: Apex Triggers
Question #7 - Build and polish Lightning Web Components, Aura components, and Visualforce basics to deliver intuitive, responsive interfaces that drive user adoption and productivity
A developer needs to create a Lightning Web Component that allows users to select multiple Contacts from a searchable list and add them to a Campaign.
Which design approach should the developer follow?
A) Build the component as an Aura component since LWC does not support complex interactions
B) Create a parent LWC for the Campaign context and child components for search and selection, communicating via custom events
C) Use a Visualforce page embedded in an iframe within the Lightning page
D) Build the entire component as a single LWC with all logic in one JavaScript file
Show solution
Correct answers: B – Explanation:
Component composition with parent-child architecture follows LWC best practices. Child components handle search and selection, firing custom events to the parent. This makes each component reusable and testable. Single-file components become unwieldy. LWC fully supports complex interactions. Visualforce in iframes bypasses Lightning design patterns. Source: Trailhead: LWC Basics
Question #8 - Streamline and scale Apex triggers, classes, and interfaces to eliminate repetitive manual work and enforce consistent business logic across teams
A developer needs to schedule an Apex class to run every weekday at 6:00 AM to aggregate daily sales data.
Which CRON expression should the developer use when calling System.schedule()?
A) ‘0 0 6 ? * 2-6’
B) ‘0 6 * * MON-FRI’
C) ‘0 0 6 * * 1-5’
D) ‘0 0 6 ? * MON-FRI’
Show solution
Correct answers: D – Explanation:
The Salesforce CRON expression format is: Seconds Minutes Hours Day_of_month Month Day_of_week. ‘0 0 6 ? * MON-FRI’ means at 6:00:00 AM, any day of month (?), any month (*), Monday through Friday. The ? character is used when Day_of_week is specified. Other formats use incorrect syntax for Salesforce’s CRON implementation. Source: Salesforce Docs: Apex Developer Guide
Question #9 - Streamline and scale Apex triggers, classes, and interfaces to eliminate repetitive manual work and enforce consistent business logic across teams
A developer is building a feature where creating a Case with ‘Priority’ set to ‘Critical’ should automatically create a Task assigned to the Case owner’s manager.
Which approach is most appropriate following Salesforce development best practices?
A) A scheduled flow that periodically checks for new Critical cases
B) A combination of both — a flow for the criteria check and a trigger for Task creation
C) A record-triggered flow, because Salesforce recommends Flow-first for business logic automation
D) An Apex after-insert trigger, because the logic requires querying the user hierarchy
Show solution
Correct answers: C – Explanation:
Salesforce recommends a Flow-first approach for business automation. Record-triggered flows can evaluate field values, query related records including User hierarchy, and create Tasks without code. While triggers can accomplish this, they should be reserved for logic that cannot be handled declaratively. Combining both adds complexity. Scheduled flows introduce delays. Source: Trailhead: Flow Builder
Question #10 - Build and polish Lightning Web Components, Aura components, and Visualforce basics to deliver intuitive, responsive interfaces that drive user adoption and productivity
A developer is debugging a Visualforce page that intermittently displays stale data from a custom controller. Users sometimes see data that was updated minutes ago by another user.
What is the most likely cause of this issue?
A) The Visualforce page is being served from a CDN cache
B) The Account records are locked by another transaction
C) The controller is using a cached SOQL query result and needs to re-query on each page load
D) The view state is caching the old data between page refreshes
Show solution
Correct answers: D – Explanation:
Visualforce view state preserves the state of the controller between postbacks, which can include previously queried data. If the controller does not re-query on each request, the view state serves the old data. SOQL does not cache results natively. Visualforce pages are not served from CDN. Record locks prevent updates, not reads. Source: Salesforce Docs: Visualforce Guide
Get 2354+ more questions with source-linked explanations
Every answer traces to the exact Salesforce documentation page — so you learn from the source, not just memorize answers.
Exam mode & learn mode · Score by objective · Updated 14-Apr-26
Learn more...
What the Certified Platform Developer exam measures
- Handle and manage multi-tenant architecture, MVC pattern, and governor limits to deliver reliable platform solutions that meet real-world business demands
- Streamline and scale Apex triggers, classes, and interfaces to eliminate repetitive manual work and enforce consistent business logic across teams
- Build and polish Lightning Web Components, Aura components, and Visualforce basics to deliver intuitive, responsive interfaces that drive user adoption and productivity
- Validate and troubleshoot test classes, debug logs, and deployment tools to catch issues before they reach production and maintain code quality across releases
How to prepare for this exam
- Cross-reference with the official exam guide for any gaps
- Complete the Platform Developer I trail on Trailhead, focusing on Apex Basics, Apex Triggers, and Lightning Web Components modules
- Build a real application in a Developer Org — create triggers, test classes, and at least two custom LWC components that interact with each other
- Contribute to an open-source Salesforce project on GitHub or build an internal tool at your workplace to gain production coding experience
- Study one objective at a time — Process Automation and Logic is the largest section, so prioritize mastering Apex patterns first
- Use PowerKram’s learn mode for objective-by-objective study with code-level explanations
- Run timed practice tests in PowerKram’s exam mode to build confidence under pressure
Career paths and salary outlook
Salesforce developers are among the highest-paid professionals in the CRM ecosystem:
- Salesforce Developer — $95,000–$135,000 per year, writing Apex, LWC, and integrations (Glassdoor salary data)
- Senior Salesforce Developer — $130,000–$170,000 per year, leading development teams and architecting solutions (Indeed salary data)
- Salesforce Technical Lead — $140,000–$185,000 per year, setting technical direction and mentoring developers (Glassdoor salary data)
Official resources
Follow the Platform Developer I Learning Path on Trailhead. The official exam guide details every objective and the passing score.
