Learn Testing, Debugging, and Deployment (PD1) with Interactive Flashcards

Master key concepts in Testing, Debugging, and Deployment through our interactive flashcard system. Click on each card to reveal detailed explanations and enhance your understanding.

Apex Testing Framework and Requirements

The Apex Testing Framework is a built-in testing infrastructure provided by Salesforce to ensure code quality, reliability, and proper functionality before deployment. It is a critical component of the Salesforce development lifecycle and a key topic for the Platform Developer I certification.

**Key Requirements:**

1. **Code Coverage:** Salesforce mandates a minimum of 75% overall Apex code coverage to deploy code to a production environment. Each trigger must also have at least 1% coverage. However, best practice recommends aiming for 90%+ coverage with meaningful assertions.

2. **Test Classes and Methods:** Test classes are annotated with `@isTest`, which ensures they do not count against the org's Apex code size limit. Test methods must be static, return void, and also use the `@isTest` annotation or the `testMethod` keyword.

3. **Assertions:** Tests must include assertions such as `System.assertEquals()`, `System.assertNotEquals()`, and `System.assert()` to verify expected outcomes. Tests without assertions are considered incomplete as they only validate that code runs without errors, not that it produces correct results.

4. **Test Data Isolation:** By default, test methods cannot access org data. You must create test data within the test method or use `@isTest(SeeAllData=true)` sparingly. The `@TestSetup` method allows creating reusable test data for all test methods in a class, improving efficiency.

5. **Test.startTest() and Test.stopTest():** These methods reset governor limits within the test context, allowing developers to test code against fresh limits. `Test.stopTest()` also ensures asynchronous operations complete synchronously.

6. **Testing Best Practices:** Tests should cover positive scenarios (valid data), negative scenarios (invalid data, exceptions), bulk operations (200+ records to test governor limits), and user permissions using `System.runAs()`.

7. **Test Utilities:** Developers often create utility classes annotated with `@isTest` to generate reusable test data across multiple test classes.

The framework supports testing triggers, classes, batch jobs, future methods, callouts (using mock interfaces like `HttpCalloutMock`), and scheduled Apex, ensuring comprehensive validation of all application logic before production deployment.

Writing Test Classes and Methods

Writing Test Classes and Methods is a critical skill for Salesforce Platform Developer I certification. In Salesforce, test classes validate that your Apex code functions correctly and are required for deploying code to production, where a minimum of 75% code coverage is mandatory.

**Test Class Structure:**
Test classes are annotated with `@isTest`, which ensures they don't count against org's Apex code limits. Test methods are defined as `static void` and annotated with `@isTest` or using the `testMethod` keyword.

```apex
@isTest
private class MyTestClass {
@isTest
static void testMyMethod() {
// Test logic here
}
}
```

**Key Principles:**
1. **Create Test Data:** Tests should create their own data rather than relying on existing org data. Use `@TestSetup` methods to create reusable test data across multiple test methods.
2. **Test.startTest() and Test.stopTest():** These methods reset governor limits within the test context, allowing you to test code against fresh limits. `stopTest()` also forces asynchronous operations to complete synchronously.
3. **System.assert Methods:** Use `System.assertEquals()`, `System.assertNotEquals()`, and `System.assert()` to verify expected outcomes.
4. **Positive and Negative Testing:** Test both valid scenarios (happy path) and invalid scenarios (error handling, boundary conditions).
5. **Bulk Testing:** Test with multiple records (typically 200+) to ensure code handles bulk operations properly.

**Best Practices:**
- Use `@isTest(SeeAllData=false)` (default) to isolate test data
- Test different user profiles using `System.runAs()`
- Cover trigger scenarios, exception handling, and edge cases
- Avoid hardcoded IDs
- Test with both single and bulk records

**@TestSetup Example:**
```apex
@TestSetup
static void setupData() {
Account acc = new Account(Name='Test');
insert acc;
}
```

Test classes cannot be deployed to production themselves but are essential for validating business logic, ensuring governor limit compliance, and maintaining code quality throughout the development lifecycle.

Test Data Management and Isolation

Test Data Management and Isolation is a critical concept in Salesforce development that ensures test methods operate independently and reliably without depending on or affecting existing org data.

**Test Data Isolation:**
By default, Salesforce test methods cannot access org data. This is enforced through the `@isTest` annotation, which creates an isolated test context. Tests run in their own transaction and any data created during the test is automatically rolled back after execution. This ensures that tests don't pollute the org with test records and don't rely on data that may change over time.

If org data access is absolutely necessary, you can use `@isTest(SeeAllData=true)`, but this is strongly discouraged as it creates fragile tests that may fail when org data changes.

**Test Data Creation:**
Best practices recommend creating all necessary test data within the test method or using utility/factory classes. A common pattern is creating a `TestDataFactory` class annotated with `@isTest` that contains static methods to generate test records such as Accounts, Contacts, Opportunities, and custom objects. This promotes code reuse and maintainability across multiple test classes.

**@TestSetup Method:**
Salesforce provides the `@TestSetup` annotation for methods that create common test data used across multiple test methods within the same class. This method runs once before all test methods, and each test method gets its own copy of the data (rolled back independently). This improves test performance by reducing redundant data creation.

**Key Considerations:**
- System records like Users, Profiles, and RecordTypes are accessible without `SeeAllData=true`
- Test data should cover various scenarios: positive, negative, bulk, and edge cases
- Tests should create data in bulk (at least 200 records) to validate governor limit compliance
- Each test method should be self-contained and not depend on execution order
- Use `Test.startTest()` and `Test.stopTest()` to reset governor limits within tests

Proper test data management ensures reliable, maintainable tests that accurately validate business logic while maintaining the required 75% code coverage minimum for deployment.

Test.startTest() and Test.stopTest()

Test.startTest() and Test.stopTest() are critical methods in Apex testing that define a controlled execution context within a test method. Together, they establish a fresh set of governor limits, allowing developers to accurately test their code without being impacted by the setup operations performed before the test logic begins.

**Test.startTest():**
This method marks the beginning of the actual test execution phase. Any code written before this call is typically used for setting up test data (e.g., inserting records, creating objects). Once Test.startTest() is called, Salesforce resets the governor limits, giving the code between startTest() and stopTest() its own independent set of limits. This ensures that data setup operations do not consume limits that would otherwise be needed for the code under test.

**Test.stopTest():**
This method marks the end of the test execution phase. It signals Salesforce to enforce the governor limits collected between startTest() and stopTest(). Importantly, Test.stopTest() also forces any asynchronous operations (such as @future methods, Queueable jobs, Batch Apex, and scheduled Apex) that were invoked between startTest() and stopTest() to execute synchronously. This allows developers to verify the results of asynchronous code immediately after stopTest() is called.

**Key Benefits:**
1. **Governor Limit Isolation:** Setup code and actual test logic have separate governor limit contexts, enabling more accurate limit testing.
2. **Asynchronous Testing:** Asynchronous processes are forced to complete synchronously, making it possible to assert their outcomes within the same test method.
3. **Best Practice:** Using these methods is considered a Salesforce best practice for writing robust, reliable test classes.

**Usage Example:**
Test data is inserted before Test.startTest(). The method or trigger being tested is invoked between startTest() and stopTest(). Assertions are placed after stopTest() to validate expected outcomes.

Note: Each test method can only call Test.startTest() and Test.stopTest() once. They must always be used as a pair within the same test method.

System.runAs() and Security Testing

System.runAs() is a critical method in Apex testing that allows developers to execute code in the context of a specific user, enabling robust security testing within Salesforce. This method is essential for verifying that sharing rules, field-level security, and profile-based permissions function correctly.

**System.runAs() Overview:**
By default, Apex test methods run under the context of the user executing the tests, with system-level permissions. System.runAs() overrides this behavior by simulating a specific user's access level. It accepts a User object as a parameter and executes the enclosed code block as that user.

**Key Features:**
- It does NOT enforce field-level security (FLS) or CRUD permissions in Apex code by default, but it DOES enforce sharing rules and record-level access.
- It resets governor limits within its block, providing a fresh set of limits.
- It allows testing with users created within the test method itself, without requiring DML commits for the user record outside the runAs block.
- It is only available in test methods; it cannot be used in production Apex code.

**Security Testing Applications:**
1. **Profile-Based Testing:** Create users with different profiles and verify they can only access appropriate records and functionality.
2. **Sharing Rule Validation:** Test that organization-wide defaults and sharing rules properly restrict or grant record access.
3. **Role Hierarchy Testing:** Verify that users higher in the role hierarchy can access subordinates' records.
4. **Permission Set Testing:** Assign permission sets to test users and validate elevated access scenarios.

**Example Pattern:**
```apex
User testUser = new User(ProfileId = restrictedProfileId, ...);
System.runAs(testUser) {
// Code runs as testUser
// Assert that restricted operations fail
// Assert that permitted operations succeed
}
```

**Best Practices:**
- Always test both positive (access granted) and negative (access denied) scenarios.
- Combine System.runAs() with assertions to validate expected behavior.
- Use separate test methods for different user contexts to maintain clarity.

System.runAs() is indispensable for ensuring your application respects Salesforce's security model and data access controls.

Testing Triggers, Controllers, and Flows

Testing Triggers, Controllers, and Flows is a critical component of Salesforce development and the Platform Developer I certification. Salesforce requires a minimum of 75% code coverage for deployment, making robust testing essential.

**Testing Triggers:**
Trigger tests validate that automation logic fires correctly on DML operations (insert, update, delete, undelete). Best practices include testing bulk operations (200+ records), verifying positive and negative scenarios, and ensuring trigger handlers execute properly. Use @isTest annotation, Test.startTest()/Test.stopTest() to reset governor limits, and System.assert() methods to validate outcomes. Always test with different user profiles to verify sharing and security rules.

**Testing Controllers:**
For Standard Controllers, test extensions by instantiating the StandardController with a test record and passing it to the extension. For Custom Controllers, test all action methods, getter/setter properties, and page references. Use Test.setCurrentPage() to set the PageReference context, and ApexPages.currentPage().getParameters() to simulate URL parameters. Verify that controller methods return correct PageReferences, error messages via ApexPages.hasMessages(), and view state data.

**Testing Flows:**
Flows (Screen Flows, Record-Triggered Flows, Autolaunched Flows) can be tested using Apex tests. Use Flow.Interview to invoke flows programmatically, passing input variables and verifying output variables. For Record-Triggered Flows, create test data that meets flow entry criteria and verify the expected automation results. Test exception handling and fault paths to ensure graceful error management.

**Best Practices:**
- Use @TestSetup methods to create reusable test data
- Never use SeeAllData=true unless absolutely necessary
- Test governor limit compliance with bulk data
- Validate both expected successes and expected failures
- Use System.assertEquals() with meaningful error messages
- Test as different user contexts using System.runAs()
- Mock external callouts using HttpCalloutMock interface

Comprehensive testing ensures reliable deployments, prevents regressions, and maintains data integrity across your Salesforce org.

Mock Testing for Callouts

Mock Testing for Callouts in Salesforce is a crucial technique for testing Apex code that makes HTTP callouts to external services. Since Salesforce does not allow real HTTP callouts during test execution, developers must use mock callouts to simulate external service responses.

There are two primary approaches to implement mock callouts:

1. **HttpCalloutMock Interface**: You create a class that implements the `HttpCalloutMock` interface and define the `respond()` method. This method returns a fabricated `HttpResponse` object that mimics the external service's response, including status codes, headers, and body content. In your test method, you use `Test.setMock(HttpCalloutMock.class, new YourMockClass())` to instruct Salesforce to use your mock instead of making a real callout.

2. **StaticResourceCalloutMock**: You can store mock response data in a Static Resource and use `StaticResourceCalloutMock` to automatically return that content. This is useful for complex JSON or XML responses that are easier to manage as static files.

Key concepts include:

- **Test.setMock()**: This method registers the mock implementation before the callout is invoked. It must be called within the test method before the code that performs the callout.

- **MultiStaticResourceCalloutMock**: Allows mapping different endpoints to different static resources when your code makes multiple callouts to various endpoints.

- **HttpCalloutMock for WebService callouts**: For SOAP-based callouts generated from WSDL imports, you implement `WebServiceMock` interface instead, using `Test.setMock(WebServiceMock.class, new YourWSMock())`.

Best practices include:
- Always test both success and error response scenarios
- Verify that your code properly handles different HTTP status codes (200, 400, 500, etc.)
- Ensure mock responses closely mirror actual API responses
- Test timeout and exception handling scenarios

Mock testing ensures code coverage requirements are met (minimum 75% for deployment) while validating that your callout logic correctly processes external service responses without depending on external system availability during testing.

Debug Logs and Log Levels

Debug Logs in Salesforce are detailed records of operations that occur during a transaction, such as Apex code execution, workflow rules, database operations, and system processes. They are essential tools for developers to troubleshoot issues, monitor code behavior, and optimize performance.

Debug logs capture information about database operations, system processes, Apex code execution, workflow rules, callouts, and validation rules. Each log has a maximum size of 20 MB, and Salesforce retains logs for 24 hours. You can set up debug logs for specific users via Setup > Debug Logs, or programmatically using the Developer Console.

Log Levels determine the granularity of information captured in debug logs. Salesforce provides several log level categories:

1. **Database** – Tracks DML operations, SOQL, and SOSL queries.
2. **Workflow** – Captures workflow rule evaluations and actions.
3. **Validation** – Logs validation rules and formula evaluations.
4. **Callout** – Records external HTTP callouts and web service calls.
5. **Apex Code** – Tracks Apex code execution, including variable assignments and method calls.
6. **Apex Profiling** – Captures performance metrics like cumulative resource usage and limits.
7. **Visualforce** – Logs Visualforce page events and view state.
8. **System** – Tracks system-level events like System.debug() statements.
9. **NBA** – Tracks Next Best Action events.
10. **Wave** – Logs Analytics-related events.

Each category supports levels from NONE (least detail) to FINEST (most detail): NONE, ERROR, WARN, INFO, DEBUG, FINE, FINER, and FINEST. Higher levels include all information from lower levels.

Setting appropriate log levels is critical because overly verbose logging can cause logs to exceed size limits, resulting in truncated data. Best practice is to set only the needed categories to higher levels while keeping others at lower levels.

Developers commonly use System.debug() statements in Apex code to output variable values and execution flow, which appear in the Apex Code category of debug logs. The Developer Console provides a Log Inspector for analyzing these logs efficiently.

Developer Console

The Developer Console in Salesforce is a powerful integrated development environment (IDE) accessible directly from the browser. It is a critical tool for Platform Developer I certification candidates to understand, as it plays a key role in testing, debugging, and deployment activities.

**Overview:**
The Developer Console allows developers to write, edit, test, and debug Apex code, Visualforce pages, Lightning components, and SOQL/SOSL queries without leaving the Salesforce environment. It can be accessed by clicking on the user name (or gear icon in Lightning) and selecting 'Developer Console.'

**Testing Capabilities:**
Developers can run Apex test classes and methods directly from the Developer Console. The Test menu provides options to run specific tests, all tests, or create test suites. It displays test results including pass/fail status, code coverage percentages, and detailed error messages. This is essential for ensuring the required minimum 75% code coverage for deployment.

**Debugging Features:**
The Developer Console offers robust debugging tools including:
- **Debug Logs:** View and analyze real-time execution logs that capture database operations, Apex processing, workflow execution, and system events.
- **Log Inspector:** A detailed view that provides timeline perspectives, execution trees, stack traces, and performance analysis.
- **Checkpoints:** Set checkpoints in code to capture heap snapshots and inspect variable values at specific execution points.
- **SOQL/SOSL Query Editor:** Execute queries in real-time to test and validate data retrieval logic.

**Deployment Context:**
While the Developer Console is not a direct deployment tool, it supports the deployment process by enabling developers to validate code quality, ensure adequate test coverage, and identify issues before deploying to production using tools like Change Sets or Salesforce CLI.

**Additional Features:**
- Execute Anonymous window for running ad-hoc Apex code
- View and manage log levels for different categories
- Source code editor with syntax highlighting and auto-complete

Mastering the Developer Console is essential for any Salesforce developer and is heavily tested in the Platform Developer I exam.

Salesforce CLI and Salesforce DX

Salesforce CLI (Command Line Interface) and Salesforce DX (Developer Experience) are essential tools for modern Salesforce development, particularly relevant for the Platform Developer I certification.

**Salesforce DX** is a set of tools and practices that streamline the entire development lifecycle, including coding, testing, debugging, and deployment. It introduces a source-driven development model where the source of truth shifts from the org to a version control system (like Git). This approach enables team collaboration, continuous integration, and automated testing.

**Salesforce CLI (sfdx/sf)** is the command-line tool that powers Salesforce DX. It allows developers to perform key operations directly from the terminal, including:

- **Project Creation**: Use `sf project generate` to scaffold a new DX project with a standardized folder structure.
- **Org Management**: Create and manage Scratch Orgs (temporary, configurable environments) using `sf org create scratch`, and authorize orgs with `sf org login web`.
- **Source Deployment & Retrieval**: Push metadata to scratch orgs (`sf project deploy start`) and pull changes back (`sf project retrieve start`), enabling seamless synchronization between local source and orgs.
- **Testing**: Run Apex tests directly via CLI with `sf apex run test`, which is critical for validating code coverage requirements (minimum 75%) before deployment.
- **Debugging**: Execute anonymous Apex (`sf apex run`) and review debug logs to troubleshoot issues.
- **Package Development**: Create and manage unlocked packages or managed packages for modular deployment.

For **Testing, Debugging, and Deployment**, Salesforce CLI enables developers to:
1. Automate test execution in CI/CD pipelines
2. Deploy metadata between environments using source-tracking or metadata API formats
3. Validate deployments before committing changes to production
4. Run specific test classes or test suites during deployment

The DX project structure organizes metadata in a `force-app` directory, with a `sfdx-project.json` configuration file defining project settings. Scratch org definitions (`config/project-scratch-def.json`) specify org features and settings for consistent development environments.

Understanding these tools is fundamental for efficient Salesforce development and is a key topic in the Platform Developer I exam.

Sandbox Types and Development Environments

Salesforce provides different sandbox types and development environments to support the application lifecycle, each tailored for specific purposes in development, testing, and deployment.

**Sandbox Types:**

1. **Developer Sandbox:** A lightweight copy of the production org that includes only metadata (no production data). It has a 200 MB data storage limit and is ideal for individual developers to build and test customizations. Refreshable every 1 day.

2. **Developer Pro Sandbox:** Similar to a Developer Sandbox but with a larger 1 GB data storage limit. It is suited for more extensive development and testing tasks, including data loading and integration testing. Refreshable every 1 day.

3. **Partial Copy Sandbox:** Contains metadata plus a sample of production data defined by a sandbox template. It has 5 GB of data storage and is ideal for testing, training, and quality assurance with realistic data sets. Refreshable every 5 days.

4. **Full Sandbox:** A complete replica of the production org, including all metadata and data. It matches production storage limits and is used for performance testing, load testing, staging, and user acceptance testing (UAT). Refreshable every 29 days.

**Development Environments:**

- **Scratch Orgs:** Temporary, configurable environments used in Salesforce DX development. They are source-driven, disposable, and ideal for agile development workflows. Developers define org shape through configuration files.

- **Developer Edition Orgs:** Free, standalone environments with limited storage used for learning, exploring features, and building apps for distribution on AppExchange.

**Key Considerations:**

- Sandboxes are connected to a production org and support deployment via change sets, metadata API, or Salesforce CLI.
- Scratch orgs support modern source-driven development and CI/CD pipelines.
- Choosing the right environment depends on the development phase: coding (Developer/Scratch), integration testing (Developer Pro/Partial Copy), and UAT/staging (Full Sandbox).

Understanding these environments is critical for Platform Developer I, as proper environment selection ensures efficient development workflows and reliable deployment processes.

Deployment Tools and Processes

Deployment Tools and Processes in Salesforce involve moving metadata, code, and configurations between environments such as development, testing, staging, and production. Understanding these tools is essential for the Platform Developer I certification.

**Key Deployment Tools:**

1. **Change Sets:** A point-and-click tool available natively in Salesforce. Outbound change sets are created in the source org and sent to a connected target org via deployment connections. They support a wide range of metadata components but lack version control and are limited to related orgs.

2. **Salesforce CLI (SFDX):** A command-line interface used with Salesforce DX for source-driven development. It supports scratch orgs, version control integration (e.g., Git), and enables continuous integration/continuous deployment (CI/CD) pipelines. Commands like `sf project deploy start` are used to push metadata to orgs.

3. **Metadata API:** The underlying API that powers most deployment tools. It allows developers to retrieve, deploy, create, update, and delete metadata programmatically using package.xml manifests. Tools like ANT Migration Tool leverage this API.

4. **ANT Migration Tool:** A Java/ANT-based tool that uses Metadata API for scripted deployments. It is useful for automated and repeatable deployments but is being gradually replaced by Salesforce CLI.

5. **VS Code with Salesforce Extensions:** Provides an integrated development environment for deploying and retrieving metadata directly from Salesforce orgs using SFDX commands.

**Deployment Processes:**

- **Validation:** Before deploying, you can validate a deployment to check for errors without committing changes. This runs all specified Apex tests.
- **Apex Test Execution:** Production deployments require at least 75% code coverage. Specific test levels include NoTestRun, RunSpecifiedTests, RunLocalTests, and RunAllTestsInOrg.
- **Quick Deploy:** After a successful validation, you can perform a quick deploy within 10 days, bypassing re-running tests.
- **Rollback:** Salesforce does not offer automatic rollback; failed deployments must be manually corrected or redeployed from a previous state.

Choosing the right tool depends on team size, complexity, and development methodology. Modern best practices favor Salesforce CLI with source control for scalable, automated deployments.

Deployment Requirements and Test Execution

In Salesforce development, deployment requirements and test execution are critical components of the application lifecycle, especially for the Certified Platform Developer I exam.

**Deployment Requirements:**
Salesforce enforces strict rules when deploying code to production environments. A minimum of 75% overall code coverage is required across all Apex classes and triggers in the organization. No single Apex trigger can have 0% code coverage — every trigger must have at least some test coverage. All tests must pass successfully before deployment is permitted. These requirements ensure code reliability and quality in production.

When deploying using Change Sets, Metadata API, or tools like Salesforce CLI (SFDX), the platform automatically runs relevant tests. For production deployments, you can choose test levels: Run Local Tests (excludes managed package tests), Run All Tests, Run Specified Tests, or the default behavior depending on deployment method.

**Test Execution:**
Apex test classes are annotated with @isTest, and test methods use @isTest or the testMethod keyword. Tests run in an isolated context — they do not have access to existing organization data by default unless @isTest(SeeAllData=true) is specified, though this is generally discouraged.

Test methods should use Test.startTest() and Test.stopTest() to reset governor limits and ensure asynchronous operations complete. Tests must include System.assert(), System.assertEquals(), and System.assertNotEquals() statements to validate expected behavior.

Best practices include creating test data within test methods using @TestSetup methods, testing bulk operations (at least 200 records), testing positive and negative scenarios, and testing as different user profiles using System.runAs().

**Key Considerations:**
- Test classes and methods do not count against the org's code size limit
- Tests cannot send emails, make HTTP callouts (must use mock frameworks), or commit data
- Deployment validation can be performed without actual deployment to verify requirements
- Code coverage is calculated based on the number of executable lines covered versus total executable lines

Understanding these concepts is essential for passing the PD1 certification and ensuring successful Salesforce deployments.

More Testing, Debugging, and Deployment questions
650 questions (total)