Shopping cart

Subtotal:

$0.00

PDI Testing, Debugging, and Deployment

Testing, Debugging, and Deployment

Detailed list of PDI knowledge points

Testing, Debugging, and Deployment Detailed Explanation

In Salesforce development, ensuring the quality and functionality of your code is essential. Testing and debugging help catch issues early, while deployment ensures that your work moves smoothly between environments.

4.1 Unit Testing

What is Unit Testing in Salesforce?

  • Unit testing involves writing test classes to validate the functionality of your Apex code (e.g., triggers, classes, methods).
  • Salesforce requires at least 75% code coverage for all Apex classes and triggers before deploying to production.

Coverage Requirement

  • Why 75%?
    • Salesforce enforces this threshold to ensure code quality and minimize errors in production environments.
    • While 75% is the minimum, aim for 100% coverage where possible for better reliability.

How to Write a Test Class

A test class is an Apex class annotated with @isTest and contains test methods to verify code behavior.

Example Test Class

The following is a simple example of a test class for an Account trigger:

Trigger to Test:

trigger AccountTrigger on Account (before insert) {
    for (Account acc : Trigger.new) {
        acc.Description = 'Auto-generated Description';
    }
}

Test Class:

@isTest
public class AccountTest {
    @isTest
    static void testAccountTrigger() {
        // Create a new Account record
        Account acc = new Account(Name = 'Test Account');
        insert acc;

        // Validate the trigger logic
        Account insertedAcc = [SELECT Description FROM Account WHERE Id = :acc.Id];
        System.assertEquals('Auto-generated Description', insertedAcc.Description);
    }
}

Key Concepts in the Test Class

  1. Setup Test Data:

    • Create or query data to simulate real scenarios (e.g., creating an Account record).
  2. Invoke the Code:

    • Perform DML operations (like insert, update) that trigger your code.
  3. Assert Results:

    • Use System.assert methods to verify that the results match expectations.

    • Example:

      System.assertEquals(expected, actual);
      

Best Practices for Unit Testing

  • Isolate Tests: Each test method should focus on a single scenario or functionality.
  • Avoid Hard-Coded IDs: Use dynamic queries or Test.loadData() to populate data.
  • Bulk Testing: Ensure your code handles multiple records at once.
  • Negative Testing: Test invalid inputs or edge cases.

4.2 Debugging

Debugging helps identify and fix issues in your code during development.

Tools for Debugging

  1. System.debug():

    • Outputs logs for analysis.

    • Example:

      System.debug('The value of acc.Description is: ' + acc.Description);
      
  2. Developer Console:

    • A built-in tool in Salesforce to view debug logs, analyze queries, and monitor performance.
    • To use:
      • Open Developer Console.
      • Go to Debug > Open Execute Anonymous Window to run Apex code.
      • View logs under Debug > View Logs.
  3. Debug Logs:

    • Logs every step of your code execution.
    • Log Levels:
      • Debug: Logs detailed information for troubleshooting.
      • Error: Logs only errors.
      • Event: Logs significant system events.

Best Practices for Debugging

  1. Add Meaningful Debug Statements:

    • Provide context in your debug logs.

    • Example:

      System.debug('Processing Account record with ID: ' + acc.Id);
      
  2. Filter Debug Logs:

    • Use filters to focus on relevant information, especially in large logs.
  3. Leverage Developer Console Features:

    • Execution Overview: View the execution order of methods, queries, and triggers.
    • SOQL Analyzer: Analyze and optimize queries.

4.3 Deployment

After developing and testing in a sandbox or developer environment, you need to deploy your changes to production or other sandboxes.

1. Change Sets

  • What are Change Sets?
    • A tool in Salesforce to migrate metadata (e.g., Apex classes, triggers, objects) between environments.
    • Accessible via Setup > Outbound Change Sets.
  • How to Use:
    1. Create an Outbound Change Set in the source org.
    2. Add components (e.g., Apex classes, objects).
    3. Upload the change set to the target org.
    4. In the target org, validate and deploy the change set.
  • Pros:
    • Simple to use for basic deployments.
    • No external tools required.
  • Cons:
    • Limited to components supported by Salesforce.
    • Not suitable for complex deployment scenarios.

2. Salesforce DX (Developer Experience)

  • What is Salesforce DX?

    • A modern development and deployment toolset designed for source-driven development.
    • Ideal for Continuous Integration/Continuous Deployment (CI/CD).
  • Key Features:

    • Scratch Orgs: Temporary, disposable environments for development and testing.
    • CLI Commands: Manage metadata, retrieve logs, and automate tasks.
    • Version Control Integration: Works seamlessly with Git for tracking changes.
  • Deployment Workflow with Salesforce DX:

    1. Use the CLI to pull changes from a source org.
    2. Commit changes to a version control system like Git.
    3. Push changes to other orgs or environments.
  • Example Deployment Command:

    sfdx force:source:deploy -p path/to/metadata
    

Comparison of Change Sets and Salesforce DX

Feature Change Sets Salesforce DX
Ease of Use Simple, GUI-based Requires CLI and technical skills
Complexity Limited to supported metadata Handles complex deployments
CI/CD Support No Yes
Speed Manual process Automated workflows

Summary

  • Testing ensures your code works as expected and meets Salesforce’s 75% coverage requirement.
  • Debugging is essential for troubleshooting and improving code quality.
  • Deployment tools like Change Sets and Salesforce DX streamline moving code between environments.

Testing, Debugging, and Deployment (Additional Content)

1. @TestSetup Annotation

1.1 What is @TestSetup?

  • @TestSetup is a special annotation in Apex testing that creates reusable test data for multiple test methods within the same test class.
  • It improves test efficiency by reducing redundant data creation and ensuring consistent test conditions.

1.2 Why Use @TestSetup?

  • Avoid duplicate test data creation across test methods.
  • Enhance test execution speed by setting up shared data only once.
  • Ensure consistency across test cases, reducing the risk of variations due to data inconsistencies.

1.3 Example: Using @TestSetup

@isTest
public class AccountTest {

    @TestSetup
    static void setupTestData() {
        Account acc = new Account(Name = 'Test Account');
        insert acc;
    }

    @isTest
    static void testAccountTrigger() {
        Account insertedAcc = [SELECT Description FROM Account WHERE Name = 'Test Account'];
        System.assertEquals('Auto-generated Description', insertedAcc.Description);
    }
}
Possible Exam Question

"Why should you use @TestSetup in a test class?"

  • Answer: To avoid redundant data creation, speed up test execution, and ensure consistency across multiple test methods.

2. Test.startTest() and Test.stopTest()

2.1 Why Use Test.startTest() and Test.stopTest()?

  • Test.startTest() resets governor limits, providing a fresh execution context to simulate real-world concurrent transactions.
  • Test.stopTest() ends the test execution block, ensuring that asynchronous processes like Future, Queueable, and Batch Apex execute properly.
  • Useful for stress-testing Apex code within governor limits.

2.2 Example: Testing Asynchronous Apex (Future Method)

@isTest
public class AsyncTest {
    @isTest
    static void testFutureMethod() {
        Test.startTest();
        FutureClass.someFutureMethod();
        Test.stopTest();

        System.assertEquals(1, [SELECT COUNT() FROM Async_Result__c]);
    }
}
Possible Exam Question

"What is the purpose of Test.startTest() and Test.stopTest() in a test class?"

  • Answer: Test.startTest() resets governor limits and provides a fresh execution context, while Test.stopTest() ensures that asynchronous operations execute before assertions.

3. Debug Log Filtering

Your debugging explanation covers System.debug(), but filtering logs in Developer Console is crucial for analyzing large logs effectively.

3.1 How to Filter Debug Logs for System.debug()?

  1. Open Developer Console.
  2. Go to Debug > View Logs.
  3. Set the Log Level to "Debug".
  4. Select "Debug Only" to filter out unnecessary logs.

3.2 Example: Using Log Filters

System.debug('Processing Account: ' + acc.Id); // Only shows debug-level logs
Possible Exam Question

"How can you filter logs in Developer Console to show only System.debug() messages?"

  • Answer: Use the "Debug Only" filter in Developer Console to display only debug-level logs.

4. Salesforce CLI (SFDX) Deployment

Salesforce DX (SFDX) is a command-line interface for managing metadata deployment and version control.

Common SFDX Commands for Deployment

Authenticate to Salesforce
sfdx force:auth:web:login -r https://login.salesforce.com
Deploy Local Metadata to an Org
sfdx force:source:push -u MyDevOrg
Retrieve Latest Changes from Salesforce
sfdx force:source:pull -u MyDevOrg
Retrieve Specific Metadata (Apex Classes, Objects, etc.)
sfdx force:source:retrieve -m ApexClass
Deploy a Specific Apex Class
sfdx force:source:deploy -m ApexClass:MyClass
Check Deployment Status
sfdx force:mdapi:deploy:report -u MyDevOrg
Run Apex Tests from CLI
sfdx force:apex:test:run -u MyDevOrg -r human
Delete Scratch Org After Testing
sfdx force:org:delete -u MyScratchOrg
Possible Exam Question

"What SFDX command is used to deploy local metadata to Salesforce?"

  • Answer: sfdx force:source:push -u MyDevOrg

5. Deployment Pipeline (CI/CD)

5.1 What is CI/CD in Salesforce?

  • CI/CD (Continuous Integration & Deployment) automates:
    • Version control (e.g., GitHub, Bitbucket)
    • Automated testing
    • Automated deployments to different Salesforce environments
  • This ensures consistent, error-free deployments across development teams.

5.2 Common CI/CD Tools for Salesforce

Tool Functionality
GitHub Actions Automates deployments with version control
Jenkins Customizable automation for deployments
Bitbucket Pipelines CI/CD workflows for Git-based repositories
Azure DevOps Integrated CI/CD for large-scale enterprise use

5.3 Example: Automating Salesforce Deployment with GitHub Actions

name: Deploy to Salesforce
on: push
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v2
    - name: Deploy to Salesforce
      run: sfdx force:source:deploy -p force-app -u MyDevOrg
  • Whenever code is pushed to the repository, this action automatically deploys updates to Salesforce.
Possible Exam Question

"What is CI/CD in Salesforce development?"

  • Answer: CI/CD automates testing and deployment processes using tools like GitHub Actions, Jenkins, and Azure DevOps.

Frequently Asked Questions

Why must Apex code have at least 75% test coverage before deployment?

Answer:

Salesforce requires at least 75% code coverage to ensure Apex code is properly tested before being deployed to production.

Explanation:

Test coverage measures how much of the Apex code is executed by test classes. Salesforce enforces a minimum coverage threshold to reduce the risk of deploying untested code that could cause system failures.

Although the requirement is 75%, developers should aim for higher coverage to ensure critical logic is fully validated. Test classes simulate real scenarios and verify that the code behaves as expected under different conditions.

However, coverage alone does not guarantee code quality. Developers must also include meaningful assertions to verify results rather than simply executing code paths.

Demand Score: 94

Exam Relevance Score: 95

What is the purpose of Test.startTest() and Test.stopTest() in Apex test classes?

Answer:

They reset governor limits and ensure asynchronous code executes during the test.

Explanation:

Test.startTest() marks the beginning of the section of code being tested. When this method is called, Salesforce resets governor limits so the code being tested has a fresh set of limits.

Test.stopTest() marks the end of the test execution block. When it runs, Salesforce executes any asynchronous operations such as future methods, queueable jobs, or batch processes.

This mechanism ensures that asynchronous logic can be properly tested inside Apex test classes. Developers frequently use this pattern to verify behavior involving asynchronous processing or large data operations.

Demand Score: 88

Exam Relevance Score: 93

Why should developers avoid using existing organization data in test classes?

Answer:

Because tests must be independent and repeatable regardless of the data in the environment.

Explanation:

Salesforce test classes run in an isolated environment where existing data is not available by default. This ensures that tests behave consistently across different environments such as sandboxes and production.

Developers must create their own test data within the test class instead of relying on records already stored in the database. This approach guarantees that the test results remain predictable and reproducible.

Using independent test data also prevents failures caused by changes in production data. Salesforce provides tools like Test.loadData() and factory methods to simplify creating consistent test records.

Demand Score: 86

Exam Relevance Score: 91

What is the purpose of assertions in Apex test classes?

Answer:

Assertions verify that the code produces the expected results.

Explanation:

Assertions are statements used in test classes to confirm that the actual output of a method matches the expected outcome. Without assertions, a test may run successfully even if the logic produces incorrect results.

For example, after inserting records or calling a method, a developer might check that a field value changed correctly or that a related record was created.

Assertions ensure that tests validate behavior rather than simply executing code. Salesforce encourages developers to write meaningful assertions to improve the reliability of their applications and detect logic errors early in the development process.

Demand Score: 82

Exam Relevance Score: 88

Why might a deployment fail even if all tests pass?

Answer:

Because the overall organization code coverage may still be below the required 75%.

Explanation:

During deployment, Salesforce evaluates code coverage across the entire organization rather than just the classes included in the deployment package. If other classes in the organization reduce the overall coverage below the required threshold, the deployment will fail.

This situation often occurs when legacy classes have little or no test coverage. Developers must ensure that enough tests exist across the system to maintain the required minimum coverage level.

Understanding how Salesforce calculates coverage helps developers diagnose deployment failures during continuous integration and release processes.

Demand Score: 85

Exam Relevance Score: 90

What tool helps developers debug Apex code during execution?

Answer:

The Salesforce Debug Log.

Explanation:

Debug logs record detailed information about transactions executed within Salesforce. Developers can view these logs to analyze how Apex code runs, identify errors, and track variable values during execution.

Logs capture events such as method calls, SOQL queries, DML operations, and exceptions. By reviewing these logs, developers can trace the sequence of operations and determine where a problem occurred.

Debug logs are particularly useful when troubleshooting triggers, asynchronous jobs, or automation processes involving multiple components.

Demand Score: 80

Exam Relevance Score: 86

PDI Training Course