-
Notifications
You must be signed in to change notification settings - Fork 11
Checking the Workflow Run
- Repeating Actions
- Checking Action Input and Output Messages
- Checking HTTP requests in the Mock Server
- Checking Tracked Properties
- Checking Terminated Workflows
You can check (assert) the workflow run status using the TestRunner.WorkflowRunStatus
property:
// Check workflow run status
Assert.AreEqual(WorkflowRunStatus.Succeeded, testRunner.WorkflowRunStatus);
The TestRunner.WorkflowRunId
property will give you the workflow's Run Id:
// Get the Run Id
string runId = testRunner.WorkflowRunId;
You can check the response from the workflow:
// Check workflow response
Assert.AreEqual(HttpStatusCode.Unauthorized, workflowResponse.StatusCode);
Assert.AreEqual("Invalid authorization header passed", workflowResponse.Content.ReadAsStringAsync().Result);
Assert.AreEqual("text/plain; charset=utf-8", workflowResponse.Content.Headers.ContentType.ToString());
You can check the status of individual actions in the workflow run history using the TestRunner.GetWorkflowActionStatus(string actionName)
method, passing the action name as the parameter:
// Check action result
Assert.AreEqual(ActionStatus.Skipped, testRunner.GetWorkflowActionStatus("Unauthorized_Response"));
Assert.AreEqual(ActionStatus.Failed, testRunner.GetWorkflowActionStatus("Get_Customer_Details_from_Service_One"));
Assert.AreEqual(ActionStatus.Succeeded, testRunner.GetWorkflowActionStatus("Failed_Get_Response"));
Assert.AreEqual(ActionStatus.Skipped, testRunner.GetWorkflowActionStatus("Update_Customer_Details_in_Service_Two"));
Make sure the action name in the test matches the action name in the workflow.json
file, i.e. spaces replaced with underscores. The testing framework will not automatically replace spaces with underscores.
You can also check the workflow's Client Tracking Id using the TestRunner.WorkflowClientTrackingId
property:
// Check the Client Tracking Id
Assert.AreEqual("expected-tracking-id", testRunner.WorkflowClientTrackingId);
The testing framework supports the checking of actions that run inside a loop, for example an Until
loop or a ForEach
loop.
You can check the status of individual action repetitions in the workflow run history using the TestRunner.GetWorkflowActionStatus(string actionName, int repetitionNumber)
method, passing the action name and repetition number as parameters:
// Check action result
Assert.AreEqual(ActionStatus.Succeeded, testRunner.GetWorkflowActionStatus("Call_Service", 3));
Assert.AreEqual(ActionStatus.Failed, testRunner.GetWorkflowActionStatus("Call_Service", 4));
Assert.AreEqual(ActionStatus.Succeeded, testRunner.GetWorkflowActionStatus("Call_Service", 5));
In this example we expect the Call_Service
action in the third and fifth repetitions to be successful and the fourth repetition to fail.
Make sure the action name matches the action name in the workflow.json
file, i.e. spaces replaced with underscores.
You can also check the total number of repetitions for an action in a loop, and check the number of iterations for the loop itself:
// The 'Call_Service' action is inside of the 'Loop_for_each_iteration' loop
Assert.AreEqual(5, testRunner.GetWorkflowActionRepetitionCount("Loop_for_each_iteration"));
Assert.AreEqual(5, testRunner.GetWorkflowActionRepetitionCount("Call_Service"));
You can check the input and output messages for an action using the TestRunner.GetWorkflowActionInput(string actionName)
and TestRunner.GetWorkflowActionOutput(string actionName)
methods, passing the action name as the parameter:
// Check input and output messages for Parse action
JToken parseCustomerInput = testRunner.GetWorkflowActionInput("Parse_Customer");
JToken parseCustomerOutput = testRunner.GetWorkflowActionOutput("Parse_Customer");
Use the method overloads for action repetitions that run in a loop:
// Get input and output messages for the second repetition
JToken serviceOneInput2 = testRunner.GetWorkflowActionInput("Call_Service_One", 2);
JToken serviceOneOutput2 = testRunner.GetWorkflowActionOutput("Call_Service_One", 2);
The response is a JToken
that includes the details of the input and output for the action, including the input and output message bodies. The structure of the JSON and the attributes in the JToken
depends on the type of action. This example validates fields in the JSON output of a Compose action:
// Validate Customer request
JToken composeCustomerRequestOutput = testRunner.GetWorkflowActionOutput("Compose_Customer_Request");
Assert.IsNotNull(composeCustomerRequestOutput);
Assert.AreEqual(composeCustomerRequestOutput["data"]["name"].Value<string>(), "Peter Smith");
Assert.AreEqual(composeCustomerRequestOutput["data"]["address"]["line1"].Value<string>(), "23 High Street");
You can also check the requests sent to the mock HTTP server, using the TestRunner.MockRequests
property which returns a List<MockRequest>
:
// Check request to Membership API
MockRequest request = testRunner.MockRequests.First(r => r.RequestUri.AbsolutePath == "/api/v1.1/membership/customers/1234");
Assert.AreEqual(HttpMethod.Put, request.Method);
Assert.AreEqual("application/json", request.ContentHeaders["Content-Type"].First());
Assert.AreEqual("expected-api-key", request.Headers["x-api-key"].First());
Assert.AreEqual(
ContentHelper.FormatJson(ResourceHelper.GetAssemblyResourceAsString($"{GetType().Namespace}.MockData.ExpectedRequest.json")),
ContentHelper.FormatJson(request.Content));
The instances of MockRequest
in the list are sorted in chronological ascending order.
The ContentHelper.FormatJson()
method is part of the testing framework and formats JSON into a consistent format to enable reliable string comparison between the actual request and the expected request. ContentHelper.FormatXml()
can be used for the comparison of XML.
The input message for a HTTP action should match the request message that is recorded by the mock HTTP server and the same applies to the action's output message and the response that is created by the mock HTTP server. The testing framework lets you use either or both of these approaches for your test cases.
You can check the tracked properties for an action using the TestRunner.GetWorkflowActionTrackedProperties(string actionName)
method, passing the action name as the parameter:
// Check tracked properties
Dictionary<string, string> trackedProps = testRunner.GetWorkflowActionTrackedProperties("Get_Customer");
Assert.AreEqual("customer", trackedProps["recordType"]);
Assert.AreEqual("123456", trackedProps["recordId"]);
Assert.AreEqual("c2ddb2f2-7bff-4cce-b724-ac2400b12760", trackedProps["correlationId"]);
Use the method overload for action repetitions that run in a loop:
// Check tracked properties for the fourth repetition
Dictionary<string, string> trackedProps = testRunner.GetWorkflowActionTrackedProperties("Get_Customer", 4);
Stateless workflows do not record the tracked properties in the workflow run history, even when the run history is enabled using the
OperationOptions
setting. Therefore theGetWorkflowActionTrackedProperties()
method will always returnnull
for actions in a stateless workflow.
The workflow Terminate action is used to stop the run for a workflow instance, cancelling any actions that are in progress and skipping any remaining actions. The workflow action is configured with a status (Failed
, Cancelled
or Succeeded
) and an error code and message when the status is Failed
.
You can check if a workflow was terminated using the the TestRunner.WorkflowWasTerminated
property. This will return true
if the workflow run was stopped because of a Terminate action. In all other cases it will return false
.
// Check if the workflow was terminated
Assert.IsTrue(testRunner.WorkflowWasTerminated);
If a workflow was terminated with a Failed
status, you can check the termination error code and message using the TestRunner.WorkflowTerminationCode
and TestRunner.WorkflowTerminationMessage
properties:
// Check termination error code and message
Assert.AreEqual((int)HttpStatusCode.InternalServerError, testRunner.WorkflowTerminationCode);
Assert.AreEqual("Language Code 'xx-GB' is not valid", testRunner.WorkflowTerminationMessage);
If the workflow was not terminated, or terminated with a status of Cancelled
or Succeeded
, these two properties will return null
.
If a workflow uses a HTTP trigger and includes a HTTP Response action, and the workflow is terminated before the HTTP response action, the workflow response status code will be HTTP 502 (Bad Gateway). This is because the Terminate action will stop the workflow run and the HTTP Response action will never be called, resulting in no HTTP response being returned to the caller - which in this instance is the test case.
- Home
- Using the Testing Framework
- Test Configuration
- Azurite
- Local Settings File
- Test Execution Logs
- Stateless Workflows
- Handling Workflow Dependencies
- Fluent API
- Automated testing using a DevOps pipeline
- Summary of Test Configuration Options
-
Example Mock Requests and Responses
- Call a Local Function action
- Invoke Workflow action
- Built-In Connectors:
- Service Bus
- SMTP
- Storage Account
- SQL Server