Rocket ship badge DevOps Launchpad

Rob Cowell · 21st August 2024

How to test Salesforce Flows

Salesforce Flows are a powerful tool within the Salesforce platform, often created using Flow builder, that allow for the automation of complex business processes without writing code. They provide a visual interface where users can design and implement workflows by defining data manipulations, actions, and user interactions.

As with anything in Salesforce, testing these Flows is crucial to ensure that they execute as expected, handle various data inputs correctly, and interact seamlessly with other Salesforce features. In this blog post, we’ll walk through different types of Flows, strategies for testing Flows, best practices and an example of how to test a Flow with Apex.

Different types of Salesforce Flows

There are a variety of different Salesforce Flows which are used for different purposes and use cases. We’ll run through a few here.

Screen flow

Screen flows require user interaction, and can include screens, local actions, steps, choices, or dynamic choices. They can be invoked from a range of different distribution methods, including Lightning pages, Lightning web components, and custom buttons, and are used to collect data or display data to users.

Scheduled-triggered flow

Scheduled-triggered flows are set to run in the background at a set frequency and specified time (for example, weekly on a Monday at 7pm). They perform actions on batches of records, and enable you to automate updates, saving time and reducing the risk of manual data updates in your org. By scheduling these flows, you can set them to run outside of typical working hours, minimizing the potential of conflicts with users.

Record-triggered flow

Record-triggered flows automatically perform actions without any user interaction, when a record is created, updated or deleted. These could be used to automatically assign permission sets, queues or groups when a new user is created, based on specific user attributes.

Platform event-triggered flow

Platform event-triggered flows perform actions when something happens in the platform or an external system and an ‘event message’ is detected. When these messages are received, a platform event-triggered flow is launched. You can use these flows to send notifications to specific user groups when an event occurs, or to update a record based on the event information.

Autolaunched flow

An autolaunched flow, as the name suggests, is automatically launched and doesn’t require user interaction. It doesn’t support screens and local actions. Scheduled-triggered flows and record-triggered flows are both examples of autolaunched flows, but you can also set flows that have no time- or event-based triggers.

Why should you test Salesforce Flows?

There are many benefits to adopting a thorough testing approach which ensures the quality and reliability of your Salesforce Flows. It ensures that Flows perform the intended actions accurately under different scenarios, identifying debug details and helping you avoid costly errors. By verifying that Flows handle errors gracefully and do not cause unexpected behavior, you can ensure a smooth user experience. Within your test plan, it’s also important to assess whether Flows execute within acceptable time frames – especially when processing large volumes of data – in order to maintain system efficiency. Flow testing also checks that your Flows integrate properly with other Salesforce automations, Apex code, and external systems, ensuring seamless operation across your Salesforce ecosystem. Be sure to document all test details, and that you’re clear on Flow test coverage requirements before you begin testing.

Strategies for effective Flow testing

There are various strategies that you can implement to run flow tests. Bulk testing verifies that Flows can handle bulk operations correctly without hitting governor limits, ensuring they perform well under heavy data loads. Positive and negative testing involves testing with both valid and invalid inputs to ensure Flows behave as expected in all situations, identifying potential weaknesses. User permissions testing simulates different user profiles and permission sets to confirm that Flows respect Salesforce's security model, maintaining data integrity and security.

You don’t need to stick to just one of these strategies, and it may be beneficial to consider a few in combination, depending on which Flows you’re working with.

Best practices for Flow testing

Whatever type of testing you choose to use, following best practice guidelines will enhance the efficiency and coverage of your flow testing efforts. There are a few different elements to consider:

Comprehensive coverage

Aim to cover all branches and outcomes within the Flow, including decision elements, loops, and fault paths, to ensure that no scenario is overlooked.

Test in a sandbox

Always test Flows in a sandbox environment before deploying to production to avoid impacting live data and users.

Monitor and analyze Flow execution logs

Utilize debug logs and Flow execution history to identify any issues and understand how Flows behave with actual data.

Keep Flows maintainable

Design Flows with maintainability in mind, ensuring they can be easily understood and modified for testing as business processes evolve. It might also be helpful to consider documentation to support your process, and make it easy for others in your team to follow and replicate.

Generate your own data

The native Flow testing capability uses real record IDs, which can break the rule of "no hardcoded IDs" which applies across many platforms. A better practice is to use Apex tests for your Flows, allowing tests to run in a true test context.

Enhanced testing for Salesforce Flows

With Salesforce's continuous innovation, testing Flows has become more sophisticated, allowing developers and administrators to ensure their automations work flawlessly. Two significant advancements are using Apex unit tests to exercise Flows and the new feature that enables the creation of Flow tests directly from Flow debug runs.

Creating Flow tests from debug runs

Salesforce has introduced a feature that allows developers to create test records for Flows directly from Flow debug runs. This capability simplifies the process of writing test scenarios by asking you to select an actual record to work with from real data, ensuring that the test cases reflect the precise conditions and data states encountered during debugging. It also reduces the time spent setting up test environments and writing test scripts. While this is a quick and easy way to test your flows in a single environment, it uses real record data and hard codes the record IDs. As we saw above, this is not an ideal approach for ensuring your tests are portable and reliable across each of your Salesforce environments. However, it does serve as good verification as an initial first pass of testing as you build your Flow.

How to set up a debug run flow test

1. Prepare your Salesforce environment
  • Ensure you have the necessary permissions: Make sure you have the appropriate permissions in your Salesforce org to create and run flows and to view debug logs.
  • Create or identify a flow: If you don’t already have a flow to test, create a new one or select an existing flow that you want to debug.
2. Set up debug logs
  • Navigate to debug logs: In Salesforce Setup, search for "Debug Logs" and navigate to it.
  • Set up a trace flag: Click on "New" under the Debug Logs section to set up a trace flag. You’ll need to specify:
    • User: Select the user for whom the debug log will be recorded (typically yourself).
    • Start/end time: Set the time range during which the logs will be captured.
    • Log level: Choose the log level you want (e.g., fine, debug). The more detailed the log level, the more information you'll capture.
  • Save the trace flag: Once everything is configured, save the trace flag. Now, Salesforce will capture detailed logs during your flow execution.
3. Run the flow in debug mode
  • Navigate to the flow: Go to the flow you want to test.
  • Click on debug: In the Flow Builder, there’s a “Debug” button in the toolbar. Click this to start the flow in debug mode.
  • Set debug options: Depending on the flow type (screen flow, autolaunched flow, etc.), you might be prompted to enter input variables. Fill these out as needed.
  • Execute the flow: Start the flow. As it runs, Salesforce will execute each step of the flow and display debug information directly in the debug window.
4. Review the debug log
  • Check the output in the debug window: As the flow runs, the debug window will show each action being taken, any errors, and the outcomes of decisions or loops.
  • Analyze the debug log: If necessary, return to the Debug Logs section in Salesforce Setup to view more detailed logs captured by the trace flag. This can help you identify any issues not apparent in the Flow Builder's debug window.
5. Make adjustments and re-test
  • Refine your flow: Based on the debug information, make any necessary changes to your flow.
  • Re-run the debug test: Repeat the debug process to ensure your flow behaves as expected after the adjustments.
6. Disable debug logs
  • Remove or disable the trace flag: Once debugging is complete, return to the Debug Logs setup and remove or deactivate the trace flag to stop capturing logs and avoid unnecessary logging.
7. Save the debug run as a test
  • Once you have a debug run successfully passing with the expected behavior, you can create a test based on the same selected records, so that it can be executed later.

By following these steps, you can effectively set up and run a debug flow test, helping you troubleshoot and refine your Salesforce flows.

Limitations of debug run flow tests

It’s important to consider that debug run tests have a number of limitations. You can conduct a maximum of 200 tests per flow, and flow tests are only available for record-triggered and data cloud-triggered flows. Flow tests don’t support flows that run when a record is deleted, or flow paths that run asynchronously, and they don’t count towards test-coverage requirements. It’s also worth noting that formulas aren’t supported for setting test data, and you should use fixed values instead.

Using Apex unit tests to exercise Flows

Apex unit tests can now invoke Flows, enabling automated testing of Flow logic within the broader context of Salesforce application testing. This method is particularly useful for integration testing, verifying that Flows integrate correctly with Apex classes and other Salesforce automation tools. It also allows for testing how Flows handle large volumes of data and ensuring they adhere to governor limits. Additionally, it helps assess the behavior of Flows under various conditions and inputs. Moreover, you can deploy your Flows in the active state if they have suitable test coverage.

Benefits of using Apex unit tests over debug run tests

Apex unit tests offer several advantages over debug run tests, improving reliability, maintainability, and compliance in Salesforce development:

  • Automation and CI/CD integration: Unit tests can be automated in CI/CD pipelines, ensuring consistent testing before deployment.
  • Code validation and coverage: They validate changes and contribute to the required 75% code coverage for production deployments.
  • Immediate feedback: Unit tests provide quick feedback on code changes, catching issues early in development. Documentation of behavior: They serve as documentation, outlining expected behavior in different scenarios.
  • Consistency across environments: Unit tests run in consistent Salesforce environments, reducing the risk of environment-specific issues.
  • Scalability: They scale well with growing codebases, unlike manual debug tests.
  • Compliance and best practices: They align with Salesforce best practices and are often required for industry compliance.

Walkthrough on how to set up Apex unit tests for flows

Setting up Apex unit tests for flows in Salesforce involves a few steps that you should follow to ensure that your flows are properly tested and that the unit tests are integrated into your development and deployment processes. Here's a step-by-step guide:

1. Identify the Flow components to test

Begin by identifying the flows or the specific components within a flow that you want to test. These could include decisions, assignments, data manipulations, or interactions with Salesforce objects.

2. Create an Apex test class

Create an Apex test class to contain your test methods. This class will house the logic for invoking your flow and asserting the expected outcomes.

@IsTest
public class MyFlowTestClass {
    // This method runs once to set up any required data
    @TestSetup
    static void setup() {
        // Insert any data required for the flow
        Account acc = new Account(Name = 'Test Account');
        insert acc;
    }

    // Test method
    @IsTest
    static void testMyFlow() {
        // Create a new instance of the flow to be tested
        Test.startTest();
        MyFlowName flow = new MyFlowName();

        // Set flow input variables
        Map<String, Object> inputs = new Map<String, Object>();
        inputs.put('inputVariableName', 'inputValue');

        // Run the flow
        Flow.Interview.MyFlowName flowInterview = new Flow.Interview.MyFlowName(inputs);
        flowInterview.start();

        // Retrieve flow output variables
        String outputVar = (String)flowInterview.getVariableValue('outputVariableName');
	//Stop test
	Test.stopTest();
        // Assert the expected outcome
        System.assertEquals('expectedValue', outputVar);
        
    }
}
Set up test data

Use the @TestSetup annotation to create test data that your flow will operate on. This method is run once before any test methods are executed, ensuring consistent data for each test run.

@TestSetup
static void setup() {
    Account acc = new Account(Name = 'Test Account');
    insert acc;
}
4. Invoke the Flow

In your test method, invoke the flow using the Flow.Interview.<FlowName> syntax. This creates an instance of the flow and allows you to pass in any required input variables.

Flow.Interview.MyFlowName flowInterview = new Flow.Interview.MyFlowName(inputs);
flowInterview.start();
5. Set Flow inputs

Before starting the flow, set up any input variables that the flow requires. These are passed as a map of key-value pairs.

Map<String, Object> inputs = new Map<String, Object>();
inputs.put('inputVariableName', 'inputValue');
Run the Flow

Use the start() method to run the flow and then retrieve any output variables that you need to assert.

flowInterview.start();
String outputVar = (String)flowInterview.getVariableValue('outputVariableName');
7. Assert the results

Use assertions to check that the Flow's output matches the expected result. This ensures that the flow logic is working as intended.

System.assertEquals('expectedValue', outputVar);
8. Use Test.startTest() and Test.stopTest()

Wrapping your Flow invocation in Test.startTest() and Test.stopTest() ensures that your Flow is executed within a fresh governor limits context, simulating real-world usage.

Test.startTest();
// Flow execution code here
Test.stopTest();
9. Run your tests

Once your test class is set up, you can run your tests using Salesforce's UI, the Developer Console, or via an automated CI/CD pipeline to ensure your Flow behaves as expected under different scenarios.

10. Consider edge cases

Test for various edge cases such as null inputs, unexpected values, and boundary conditions to ensure that your flow handles all possible scenarios gracefully.

Example Apex test class for a Flow

@IsTest
public class AccountCreationFlowTest {
    @TestSetup
    static void setup() {
        // Insert test data required for the flow
        Account acc = new Account(Name = 'Test Account');
        insert acc;
    }

    @IsTest
    static void testAccountCreationFlow() {
        // Set input variables for the flow
        Map<String, Object> inputs = new Map<String, Object>();
        inputs.put('accountName', 'Test Account');

        // Run the flow
        Test.startTest();
        Flow.Interview.AccountCreationFlow flowInterview = new Flow.Interview.AccountCreationFlow(inputs);
        flowInterview.start();
        Test.stopTest();

        // Verify the expected outcome
        Account createdAccount = [SELECT Id, Name FROM Account WHERE Name = 'Test Account'];
        System.assertNotEquals(null, createdAccount.Id, 'Account should be created');
    }
}

By leveraging these testing strategies and best practices, you can ensure that your Salesforce Flows are robust, reliable, and ready to handle real-world scenarios. Happy testing!

Learn more about Salesforce testing

Ready to take the next step into Salesforce testing? Level up your skills and make sure your deployments are smooth and efficient with the free Salesforce testing and test automation course on DevOps Launchpad.