Introduction
I published a blog post on performance testing Dynamics 365 Finance and Operations with JMeter some time ago. If you haven’t had a chance to read it, I encourage you to take a look. Many people have asked me whether JMeter can support performance testing for Dynamics 365 CE. The answer is yes, JMeter is definitely capable of handling performance testing for Dynamics 365 CE. In this new post, I will use similar concepts and tools to perform performance testing for Dynamics 365 CE as well.
Performance testing is crucial and mandatory in implementation projects, and selecting the right tool is equally important. You need a tool with a long lifecycle that can support performance testing throughout the project. There are many performance testing tools available, but JMeter stands out as one of the most powerful. It is scalable, open-source, and can support performance testing for any web application.
While the approach to performance testing for Finance and Operations and Dynamics 365 CE is similar, the technical details may differ due to the different platforms and languages they are built on. In this session, I will demonstrate how I conduct performance testing for Dynamics 365 CE using JMeter, based on a common scenario. I hope you can then adapt this concept to your own scenario for testing Dynamics 365 CE. As mentioned, the approach is similar to Finance and Operations, so I will avoid repeating explanations from the previous post.
Pre-requisite and Configuration
There are several prerequisites and configuration requirements for conducting performance testing in Dynamics 365 CE with JMeter. For detailed steps, please refer to my blog post, Part 2 - Dynamics 365 Finance and Operations Apps Performance Testing with JMeter - Execution, and the following sections within the post to complete the necessary configurations:
I published a blog post on performance testing Dynamics 365 Finance and Operations with JMeter some time ago. If you haven’t had a chance to read it, I encourage you to take a look. Many people have asked me whether JMeter can support performance testing for Dynamics 365 CE. The answer is yes, JMeter is definitely capable of handling performance testing for Dynamics 365 CE. In this new post, I will use similar concepts and tools to perform performance testing for Dynamics 365 CE as well.
Performance testing is crucial and mandatory in implementation projects, and selecting the right tool is equally important. You need a tool with a long lifecycle that can support performance testing throughout the project. There are many performance testing tools available, but JMeter stands out as one of the most powerful. It is scalable, open-source, and can support performance testing for any web application.
While the approach to performance testing for Finance and Operations and Dynamics 365 CE is similar, the technical details may differ due to the different platforms and languages they are built on. In this session, I will demonstrate how I conduct performance testing for Dynamics 365 CE using JMeter, based on a common scenario. I hope you can then adapt this concept to your own scenario for testing Dynamics 365 CE. As mentioned, the approach is similar to Finance and Operations, so I will avoid repeating explanations from the previous post.
Pre-requisite and Configuration
There are several prerequisites and configuration requirements for conducting performance testing in Dynamics 365 CE with JMeter. For detailed steps, please refer to my blog post, Part 2 - Dynamics 365 Finance and Operations Apps Performance Testing with JMeter - Execution, and the following sections within the post to complete the necessary configurations:
- Configure a development environment
- Install Plugin (bzm – Correlation Recorder)
- Installing the JMeter CA certificate for HTTPS recording and Configure your browser to use the JMeter Proxy
- Utilizing JMeter Templates for Scenario Recording
- Configurations for Recording D365 F&O Scenarios
Before starting task recording, there are two specific considerations unique to recording scripts in the Dynamics 365 CE platform that I would like to highlight.
Adjust HTTP Sampler Settings: Dynamics 365 CE does not support the "Java" type in HTTP Sampler settings. To address this, navigate to your test plan, select the Correlation Plugin, go to the Test Plan Creation tab, and change the Type from "Java" to "Empty"
Add a Correlation Rule: After installing your correlation template, create a new correlation rule in the Correlation Plugin. Navigate to the Correlation tab in the plugin, add a new group, and name it "CRM." Then, add the following rule under the "CRM" group.
Reference Variable | Correlation Extractor | Correlation Replacement |
UserName | \\"UserName\\":\\"([^"]*)\\" | "ownerid@OData.Community.Display.V1.FormattedValue":"([^"]*)" |
TransactionCurrencyId | \\"TransactionCurrencyId\\":\\"([^"]*)\\" | "transactioncurrencyid@odata.bind":"/transactioncurrencies\(([^"]*)\)" |
UserId | \\"UserId\\":\\"([^"]*)\\" | systemusers\(([^"]*)\) |
UserId | \\"UserId\\":\\"([^"]*)\\" | "HostAppPersonaId":"systemuser:([^"]*)" |
UserId | \\"UserId\\":\\"([^"]*)\\" | "ownerid@odata.bind":"/systemusers(([^"]*))" |
contactsID | contacts\(([^)]*)\) | contacts\(([^)]*)\) |
For reference, my lab environment was set up with the following specifications to demonstrate how to conduct performance testing with JMeter:
- Operating System: Windows 11
- Browser for Recording: Firefox 133.0.3
- Java SDK: Java 13
- JMeter Version: 5.6.2
- Plugin Manager: 1.9
- Correlation Plugin: 2.5
- Dynamics 365 CE: Version 9.2.24111.222
- Project Operations installed
- Dual-Write enabled
Scenarios
In upcoming scenarios for conducting performance testing with JMeter in Dynamics 365 CE, I will demonstrate how to use JMeter to automate the testing for performance in Dynamics CE. For this example, I have chosen a common yet complex scenario: creating a Project Sales Order from Project Operations.
The steps involved are as follows:
As a result of this scenario, a new opportunity and quote will be created, activated, and marked as Won, culminating in the creation of a project contract with an associated order number. Below is an example of a project contract with a sales order generated from the opportunity.
In upcoming scenarios for conducting performance testing with JMeter in Dynamics 365 CE, I will demonstrate how to use JMeter to automate the testing for performance in Dynamics CE. For this example, I have chosen a common yet complex scenario: creating a Project Sales Order from Project Operations.
The steps involved are as follows:
- Log in to Project Operations using user credentials.
- Navigate to the Sales tab.
- Create a new project opportunity within Sales.
- Fill in all mandatory and required fields in the new opportunity.
- Add a new opportunity line to the opportunity.
- Create a new quote for the opportunity.
- Qualify the current opportunity and move it to the next stage.
- Activate the opportunity's quote.
- Mark the opportunity as Won to create a new contract.
- Sign out application
As a result of this scenario, a new opportunity and quote will be created, activated, and marked as Won, culminating in the creation of a project contract with an associated order number. Below is an example of a project contract with a sales order generated from the opportunity.
Recording step by step
After completing the JMeter configuration and creating a new JMeter Test Plan with the Correlation template according to blog post of finance and operations apps performance testing with JMeter, ensure that you provide a name for the test plan, such as Dataverse_CE_ProjOperation_CreateOpportunity.jmx.
The first step is to navigate to the User Defined Variables section and define the following variables:
After completing the JMeter configuration and creating a new JMeter Test Plan with the Correlation template according to blog post of finance and operations apps performance testing with JMeter, ensure that you provide a name for the test plan, such as Dataverse_CE_ProjOperation_CreateOpportunity.jmx.
The first step is to navigate to the User Defined Variables section and define the following variables:
Name: | Value |
host | <environment>.crm.dynamics.com |
scheme | https |
SalesNumber | SalesNumber_NOTFOUND |
appid | <Dynamics CE Appid> |
tenantID | <Tenant ID> |
Navigate to HTTP Request Defaults and provide the following information:
Navigate to the Correlation section and enable the Legacy Correlation checkbox.
Ensure that all necessary settings in the Correlation Recorder are properly configured. Once the setup is complete, go to Correlation Recorder and click the Start button to begin recording.
1. Enter "Login" as the transaction name in the Recorder. Open Dynamics 365 Project Operations in Firefox, input the username and password credentials to access the system, and then click the Next button.
2. After entering the password, set the transaction name to AccessToCEDashboard in the Recorder. Click the Yes button when prompted with the "Stay signed in" option (this setting depends on the organization's configuration).
3. Ensure that the Recording Controller in JMeter has successfully generated the sampler for the recorded steps. If no sampler is generated, identify and resolve the issue, then re-record the steps to capture the necessary actions.
- Protocol [http]: ${scheme}
- Server Name or IP: ${host}
Navigate to the Correlation section and enable the Legacy Correlation checkbox.
Ensure that all necessary settings in the Correlation Recorder are properly configured. Once the setup is complete, go to Correlation Recorder and click the Start button to begin recording.
1. Enter "Login" as the transaction name in the Recorder. Open Dynamics 365 Project Operations in Firefox, input the username and password credentials to access the system, and then click the Next button.
2. After entering the password, set the transaction name to AccessToCEDashboard in the Recorder. Click the Yes button when prompted with the "Stay signed in" option (this setting depends on the organization's configuration).
3. Ensure that the Recording Controller in JMeter has successfully generated the sampler for the recorded steps. If no sampler is generated, identify and resolve the issue, then re-record the steps to capture the necessary actions.
4. If you encounter an issue where, after logging in successfully, the system prompts you to click the Sign In button again, simply proceed by clicking the button. This will not affect the recording of your scenario.
5. When accessing the Project Operations Dashboard, set the transaction name to GoToSales in the Recorder. Next, click the Projects tab and select Sales from the Change Area menu.
6. Set the transaction name to GoToOpportunities in the Recorder. Then, click Opportunities in the left-hand menu to navigate to the Opportunities page.
7. Set the transaction name to NewOpportunity in the Recorder. Then, click the New button to create a new Opportunity.
8. Enter the mandatory and required field details in the form accordingly. You can use the following sample values for reference, but make sure to adjust them based on your specific use case:
- Topic: New Opportunity Perf 1000
- Owning Company: Contoso Robotics USA
- Contact: John Smith
- Account MWDemoCustomer3
- AccountManager Edison Lai
- Contracting Unit Contoso Robotics US
- Currency US Dollar
- Roduct Price List US Bill Rates
- Revenue User Provideded
- Budget Amount 70000
- Probability 80
- Rating Warm
- Purchase Process Committee
- Description Opportunity Perf test with JMeter
9. Set the transaction name to SaveOpportunity in the Recorder. Then, click the Save button to ensure the Opportunity is successfully saved.
10. Once the opportunity is saved, set the transaction name to GoToOpportunityLines in the Recorder. Then, click the Opportunity Lines tab and click the Add New Opportunity Line button to create a new opportunity line.
11. Set the transaction name to NewOpportunityLines in the Recorder. Then, proceed to enter the following values in the New Opportunity Line form (you can adjust the values based on your specific use case):
12.Set the transaction name to SaveOpportunityLines in the Recorder. Then, click the Save & Close button to save the opportunity line and close the current form, returning to the Opportunity form.
10. Once the opportunity is saved, set the transaction name to GoToOpportunityLines in the Recorder. Then, click the Opportunity Lines tab and click the Add New Opportunity Line button to create a new opportunity line.
11. Set the transaction name to NewOpportunityLines in the Recorder. Then, proceed to enter the following values in the New Opportunity Line form (you can adjust the values based on your specific use case):
- Product Type Project-based Service
- Opportunity New Opportunity Perf 1000
- Name Opportunity Line Perf 1000
- Customer Budget 4000
- Billing Method Time and Material
12.Set the transaction name to SaveOpportunityLines in the Recorder. Then, click the Save & Close button to save the opportunity line and close the current form, returning to the Opportunity form.
13. Once the opportunity line is saved, set the transaction name to GoToQuotes in the Recorder. Then, click the Quotes tab to navigate to the Quotes section.
14. Set the transaction name to NewQuotes in the Recorder. Then, click the New Quote button to create a new Quote.
15. Leave all fields as default, set the transaction name to SaveAndCloseQuotes, and click the Save and Close button to save the new Quote. This will return you to the New Opportunity form. The new quote should appear in the form.
16. Set the transaction name to Qualify_SelectQuote and click the Qualify step in the process flow. The required values should be provided by default based on the opportunity's data. Click the Next Stage button and select the newly created quote in the popup form.
17. Once the Qualify process is complete and the status moves to Propose, set the transaction name to ActivateQuote. Click the Activate Quote button to activate the selected quote.
18. After successfully activating the quote, the status will change to Active. Set the transaction name to CloseAsWon and click the Close as Won button in the navigation bar.
19. Wait for the processing to complete as the quote is closed.
20. Click OK to confirm and close the quote as Won if a dialog appears for confirmation.
15. Leave all fields as default, set the transaction name to SaveAndCloseQuotes, and click the Save and Close button to save the new Quote. This will return you to the New Opportunity form. The new quote should appear in the form.
16. Set the transaction name to Qualify_SelectQuote and click the Qualify step in the process flow. The required values should be provided by default based on the opportunity's data. Click the Next Stage button and select the newly created quote in the popup form.
17. Once the Qualify process is complete and the status moves to Propose, set the transaction name to ActivateQuote. Click the Activate Quote button to activate the selected quote.
18. After successfully activating the quote, the status will change to Active. Set the transaction name to CloseAsWon and click the Close as Won button in the navigation bar.
19. Wait for the processing to complete as the quote is closed.
20. Click OK to confirm and close the quote as Won if a dialog appears for confirmation.
21. After the quote is successfully closed as Won, the page will redirect to the newly created order, and a Sales Order Number will be assigned.
22. Set the transaction name to SignOut and sign out of the current session. Once signed out, click the Stop button in the Recorder to stop the recording.
Ensure that the recorder has stopped correctly, and all samplers have been captured successfully. Finally, click Save to save the Test Plan.
22. Set the transaction name to SignOut and sign out of the current session. Once signed out, click the Stop button in the Recorder to stop the recording.
Ensure that the recorder has stopped correctly, and all samplers have been captured successfully. Finally, click Save to save the Test Plan.
Post-Recording Steps in JMeter
After recording a scenario in JMeter, there are several important post-recording tasks to optimize and manage your test script effectively.
Organize the Samplers
One of the first steps is grouping the samplers based on key actions. This approach improves readability and makes the test plan easier to manage.
To do this, organize the recorded samples under the Recording Controller using Transaction Controllers or Simple Controllers. For example, you can group them into stages or logical actions, such as authentication, data retrieval, or form submission. In my case, I grouped the samples into 11 Simple Controllers, each representing a distinct stage of the process.
Clean up
Next, remove any irrelevant or unnecessary samplers. Here's how you can determine what to keep or discard:
After recording a scenario in JMeter, there are several important post-recording tasks to optimize and manage your test script effectively.
Organize the Samplers
One of the first steps is grouping the samplers based on key actions. This approach improves readability and makes the test plan easier to manage.
To do this, organize the recorded samples under the Recording Controller using Transaction Controllers or Simple Controllers. For example, you can group them into stages or logical actions, such as authentication, data retrieval, or form submission. In my case, I grouped the samples into 11 Simple Controllers, each representing a distinct stage of the process.
Clean up
Next, remove any irrelevant or unnecessary samplers. Here's how you can determine what to keep or discard:
Identify Useful Samplers: Check the Server Name or IP in the sampler. For instance, if the server name shows ${host} and the path is something like /api/data/v9.0/GetClientMetadata(ClientMetadataQuery=@ClientMetadataQuery), it indicates a standard CRM API call. Such samplers should generally be retained, as they communicate with the CRM server.
Remove or Disable Unnecessary Samplers: If the Server Name or IP appears unfamiliar or irrelevant and you’ve confirmed it is not needed, disable or delete the sampler to keep your script clean and focused.
Parameterization
Parameterization is key for making your test script dynamic and adaptable. For example, when creating a new opportunity in a CRM system, provide a random name for the opportunity. To achieve this, follow these steps to add User Parameters:
In the Test Plan, right-click the Recording Controller. Navigate to Add > Pre Processors > User Parameters.
Parameterization is key for making your test script dynamic and adaptable. For example, when creating a new opportunity in a CRM system, provide a random name for the opportunity. To achieve this, follow these steps to add User Parameters:
In the Test Plan, right-click the Recording Controller. Navigate to Add > Pre Processors > User Parameters.
Define the parameters for randomizing values, such as the opportunity name, Line name and description. Following add new variable with predefined pattern.
Name: | User_1 |
OppName | New Opportunity from JMeter ${__Random(0000,9999)} |
OppLineName | New Opportunity Line ${__Random(0000,9999)} |
OppDesc | Opportunity Perf test with JMeter |
You can add any variable to replace fixed values in your recorded script.
In the JMeter navigation bar, click Search > Search
In the Search textbox, input New Opportunity Perf 1000. In the Replace By textbox, input ${oppName}. Click Replace All. This process will update all occurrences, and in this example, 8 nodes were matched and replaced.
In the JMeter navigation bar, click Search > Search
In the Search textbox, input New Opportunity Perf 1000. In the Replace By textbox, input ${oppName}. Click Replace All. This process will update all occurrences, and in this example, 8 nodes were matched and replaced.
Check the updated sampler, e.g., SaveOpportunity/api/data/v9.0/$batch-1,152. You should see the opportunity name replaced with ${oppName}.
To ensure your script can be replayed successfully, focus on dynamic values such as GUIDs in Dynamics CE. GUIDs are critical as they represent entities, processes, workflows, and data records. You'll need to capture these GUIDs during recording and extract them for reuse in subsequent requests. Use the View Results Tree to examine responses and pinpoint HTTP request samplers containing GUIDs that are crucial for subsequent steps. Once identified, use extractors to capture GUIDs from the responses. Replace all instances of the GUID in subsequent requests with the extracted variable.
Once identified, use extractors to capture GUIDs from the responses. Replace all instances of the GUID in subsequent requests with the extracted variable. There are several extractors in JMeter, but here are two commonly used ones, If you find another extractor to be more beneficial, you are free to switch to that one.
To ensure your script can be replayed successfully, focus on dynamic values such as GUIDs in Dynamics CE. GUIDs are critical as they represent entities, processes, workflows, and data records. You'll need to capture these GUIDs during recording and extract them for reuse in subsequent requests. Use the View Results Tree to examine responses and pinpoint HTTP request samplers containing GUIDs that are crucial for subsequent steps. Once identified, use extractors to capture GUIDs from the responses. Replace all instances of the GUID in subsequent requests with the extracted variable.
Once identified, use extractors to capture GUIDs from the responses. Replace all instances of the GUID in subsequent requests with the extracted variable. There are several extractors in JMeter, but here are two commonly used ones, If you find another extractor to be more beneficial, you are free to switch to that one.
- Boundary Extractor : The Boundary Extractor in JMeter is a post-processing component, The Boundary Extractor is particularly useful when dealing with responses that have predictable patterns, making it a simpler and more efficient alternative to regular expressions in certain scenarios. E.g. Define the Left Boundary and Right Boundary to capture the desired value.
- JSON Extractor : The JSON Extractor in JMeter is a powerful tool used to parse and extract data from JSON responses, you need to define the JSON Path expressions to extract specific data from the JSON response.
I will take below example how to find the key request and how to extract the GUID from the request, In this scenario, the first step is to create an opportunity. The GUID for the new opportunity must be captured for further actions.
Open the View Results Tree. Look for the HTTP request sampler, e.g., SaveOpportunity/api/data/v9.0/$batch-1,152. Find the GUID in the response, such as (69c206a1-ad46-4b01-b6c3-787e40746810), so we can create extractor in this sampler to extractor new opportunity GUID and replace all opportunity GUID with extractor variable.
Use a Boundary Extractor in the sampler SaveOpportunity/api/data/v9.0/$batch-1,152 with below value.
Open the View Results Tree. Look for the HTTP request sampler, e.g., SaveOpportunity/api/data/v9.0/$batch-1,152. Find the GUID in the response, such as (69c206a1-ad46-4b01-b6c3-787e40746810), so we can create extractor in this sampler to extractor new opportunity GUID and replace all opportunity GUID with extractor variable.
Use a Boundary Extractor in the sampler SaveOpportunity/api/data/v9.0/$batch-1,152 with below value.
- Name Boundary: Extractor - opportunities
- Name of created variable: opportunities
- Left Boundary: opportunities(
- Right Boundary: )
- Match No.: 1
- Default Value: _opportunities_NOTFOUND_
Replace all instances of the opportunity GUID (69c206a1-ad46-4b01-b6c3-787e40746810) in subsequent requests with the extractor variable. At the end there are 145 result found and replaced by ${opportunities}. By implementing these steps, your script will dynamically handle GUIDs, making it adaptable for various test scenarios.
When an opportunity is created, the system also generates a process flow GUID. For opportunities, this GUID corresponds to the opportunitysalesprocesses entity, which is included in the sampler SaveOpportunity/api/data/v9.0/$batch-1,152.
So my option to handle the Opportunity sales process flow GUID, Duplicate the sampler SaveOpportunity/api/data/v9.0/$batch-1,152 and rename it to SaveOpportunity/api/data/v9.0/$batch-1,152 - PROCESS. Split the body data into two separate HTTP requests. And keep the first part of the body data in the original sampler.
Move the second part of the body data to the duplicated sampler (SaveOpportunity/api/data/v9.0/$batch-1,152 - PROCESS).
When an opportunity is created, the system also generates a process flow GUID. For opportunities, this GUID corresponds to the opportunitysalesprocesses entity, which is included in the sampler SaveOpportunity/api/data/v9.0/$batch-1,152.
So my option to handle the Opportunity sales process flow GUID, Duplicate the sampler SaveOpportunity/api/data/v9.0/$batch-1,152 and rename it to SaveOpportunity/api/data/v9.0/$batch-1,152 - PROCESS. Split the body data into two separate HTTP requests. And keep the first part of the body data in the original sampler.
Move the second part of the body data to the duplicated sampler (SaveOpportunity/api/data/v9.0/$batch-1,152 - PROCESS).
Create Boundary Extractor, In the sampler SaveOpportunity/api/data/v9.0/$batch-1,152 - PROCESS, add a Boundary Extractor with the following configuration:
Adjust to Your Script: The sampler numbers in your script may differ, which is entirely normal. Use the Result Tree to cross-check your recorded script, identify key GUIDs, and replace them with variables. Apply the concepts described earlier to parameterize all essential GUIDs in your script. Below are examples of extractors created in my script for reference:
- Name Boundary: Extractor - opportunitysalesprocesses
- Name of created variable: opportunitysalesprocesses
- Left Boundary: opportunitysalesprocesses(
- Right Boundary: )
- Match No.: 1
- Default Value: _opportunitysalesprocesses_NOTFOUND_
Adjust to Your Script: The sampler numbers in your script may differ, which is entirely normal. Use the Result Tree to cross-check your recorded script, identify key GUIDs, and replace them with variables. Apply the concepts described earlier to parameterize all essential GUIDs in your script. Below are examples of extractors created in my script for reference:
Extractor for Process Activity and Stage ID: This extractor retrieves the activity and stage ID associated with the process.
Extractor for Opportunity ID and Corresponding Process ID: Use this extractor to capture the opportunity ID and its linked process ID.
Extractor for Quote ID: This extractor is used to retrieve the quote ID
Extractor for Entity ID: Retrieve specific entity IDs required for subsequent requests using this extractor.
Extractor for Sales Order Number: This extractor captures the sales order number for later use.
Execution of Single-User Tests to validate the test script
Once you've reshaped the script, replay it to ensure it functions correctly. Test whether the script can create new Opportunity, Line, Quote and Project order.
Extractor for Opportunity ID and Corresponding Process ID: Use this extractor to capture the opportunity ID and its linked process ID.
Extractor for Quote ID: This extractor is used to retrieve the quote ID
Extractor for Entity ID: Retrieve specific entity IDs required for subsequent requests using this extractor.
Extractor for Sales Order Number: This extractor captures the sales order number for later use.
Execution of Single-User Tests to validate the test script
Once you've reshaped the script, replay it to ensure it functions correctly. Test whether the script can create new Opportunity, Line, Quote and Project order.
For testing, set the Thread Count to 10 to simulate 10 simultaneous requests. This should result in the creation of 10 opportunities and associated project contacts.
The screenshot below shows that new project orders were successfully created, each with a unique random number in the opportunity name.
If Dual-Write is enabled, verify that the project contract is synchronized with Finance and Operations.
The screenshot below shows that new project orders were successfully created, each with a unique random number in the opportunity name.
If Dual-Write is enabled, verify that the project contract is synchronized with Finance and Operations.
Execution of Multi-User Tests
After successfully validating the script with single-user tests, it is ready to proceed with multi-user testing. Similar to the multi-user testing process in Finance and Operations, real Azure Active Directory (AAD) users are required. You can refer to the Execution of Multi-User Tests section in Part 2 - Dynamics 365 Finance and Operations Apps Performance Testing with JMeter - Execution for detailed guidance.
In this scenario, I created 5 additional user accounts and assigned appropriate roles in CE for each user. Next, I included a CSV Data Set Config in the Test Plan and populated the CSV file with the users' email addresses and passwords.
Replace all occurrences of the user email by using the Search tool. Enter the captured user email in the Search field and replace it with ${userEmail}, then click Replace All.
Similarly, replace all occurrences of the user password. Enter the captured password in the Search field, replace it with ${userPassword}, and click Replace All.
Set the Thread Count to 20 to simulate 20 simultaneous requests. Additionally, a Loop Controller has been added for each thread, resulting in the creation of 60 opportunities and their associated project contacts.
Disable all listeners and non-test elements, keeping only the executable transaction script active within the Test Plan.
Open Command Prompt with Administrator privileges and navigate to the \bin directory where the jmeter.bat execution application is located. Run the following command, referring to the documentation for additional details on command parameters:
After successfully validating the script with single-user tests, it is ready to proceed with multi-user testing. Similar to the multi-user testing process in Finance and Operations, real Azure Active Directory (AAD) users are required. You can refer to the Execution of Multi-User Tests section in Part 2 - Dynamics 365 Finance and Operations Apps Performance Testing with JMeter - Execution for detailed guidance.
In this scenario, I created 5 additional user accounts and assigned appropriate roles in CE for each user. Next, I included a CSV Data Set Config in the Test Plan and populated the CSV file with the users' email addresses and passwords.
Replace all occurrences of the user email by using the Search tool. Enter the captured user email in the Search field and replace it with ${userEmail}, then click Replace All.
Similarly, replace all occurrences of the user password. Enter the captured password in the Search field, replace it with ${userPassword}, and click Replace All.
Set the Thread Count to 20 to simulate 20 simultaneous requests. Additionally, a Loop Controller has been added for each thread, resulting in the creation of 60 opportunities and their associated project contacts.
Disable all listeners and non-test elements, keeping only the executable transaction script active within the Test Plan.
Open Command Prompt with Administrator privileges and navigate to the \bin directory where the jmeter.bat execution application is located. Run the following command, referring to the documentation for additional details on command parameters:
Jmeter.bat -n -t "C:\apache-jmeter\bin\CE_Dataverse\Dataverse_CE_ProjOperation_CreateOpportunity.jmx" -l "C:\apache-jmeter\bin\CE_Dataverse\Result\Results.csv" -e -o "C:\apache-jmeter\bin\CE_Dataverse\Result\Report"
A successful execution of this command will result in the following outcome:
The successful test outcome is demonstrated by the creation of project opportunities that completed their processes seamlessly by different testing users. These opportunities were marked as WON, leading to the successful generation of project orders.
The JMeter HTML Report is generated side by side the test execution, as the script includes output parameters. You can locate the HTTP report at the specified path: \bin\CE_Dataverse\Result\Report, within this directory, you will find a dashboard containing detailed and relevant information about the test results.
The HTML report offers a comprehensive view of graphs and results, making it easier to analyze the test performance. For more details, refer to the dashboard or consult the Apache JMeter - User's Manual: Generating Dashboard Report
The successful test outcome is demonstrated by the creation of project opportunities that completed their processes seamlessly by different testing users. These opportunities were marked as WON, leading to the successful generation of project orders.
The JMeter HTML Report is generated side by side the test execution, as the script includes output parameters. You can locate the HTTP report at the specified path: \bin\CE_Dataverse\Result\Report, within this directory, you will find a dashboard containing detailed and relevant information about the test results.
The HTML report offers a comprehensive view of graphs and results, making it easier to analyze the test performance. For more details, refer to the dashboard or consult the Apache JMeter - User's Manual: Generating Dashboard Report
Azure Load Testing
As mentioned in the Finance and Operations testing with JMeter, I recommend using Azure Load Testing (ALT) for performance testing due to its scalability and portability. ALT allows you to execute the testing script from anywhere, anytime, making it an ideal solution.
The first step is to parameterize all variables in the User Default Variable, which you will define via the ALT Test Plan for each test. You can find more details on how to parameterize variables for ALT in the documentation.
Once parameterization is complete, you can create a new Azure Load Test in the Azure portal. Then, upload your JMX script and the configuration file, such as CRM_login.csv, to the newly created test plan. After reviewing the test settings, save the new test plan.
Once the test plan is created and the script is validated, you can proceed with conducting the test in Azure Load Testing (ALT). Below is the result of ALT after I conducted the multiple user testing.
You will achieve the same testing results (Created Opportunities, Lines, Quote and Project contract) as with multiple user testing through the JMeter command in CMD, but without needing to worry about the resource limitations of the machine running the script.
As mentioned in the Finance and Operations testing with JMeter, I recommend using Azure Load Testing (ALT) for performance testing due to its scalability and portability. ALT allows you to execute the testing script from anywhere, anytime, making it an ideal solution.
The first step is to parameterize all variables in the User Default Variable, which you will define via the ALT Test Plan for each test. You can find more details on how to parameterize variables for ALT in the documentation.
Once parameterization is complete, you can create a new Azure Load Test in the Azure portal. Then, upload your JMX script and the configuration file, such as CRM_login.csv, to the newly created test plan. After reviewing the test settings, save the new test plan.
Once the test plan is created and the script is validated, you can proceed with conducting the test in Azure Load Testing (ALT). Below is the result of ALT after I conducted the multiple user testing.
You will achieve the same testing results (Created Opportunities, Lines, Quote and Project contract) as with multiple user testing through the JMeter command in CMD, but without needing to worry about the resource limitations of the machine running the script.
Summary
In this blog post, I have outlined the approach and concepts for leveraging JMeter to conduct both single-user and multiple-user tests for Dynamics 365 CE. By integrating the techniques shared in my other blog post on JMeter for Finance and Operations, you can efficiently perform joint performance testing for both Finance and Operations apps as well as CE using JMeter.
In this blog post, I have outlined the approach and concepts for leveraging JMeter to conduct both single-user and multiple-user tests for Dynamics 365 CE. By integrating the techniques shared in my other blog post on JMeter for Finance and Operations, you can efficiently perform joint performance testing for both Finance and Operations apps as well as CE using JMeter.
*This post is locked for comments