Automated testing used to be difficult with Logic Apps, but that’s no longer the case with the addition of Logic Apps Standard. As it is based on the Azure Functions runtime, it can run anywhere, and we can write tests for workflows that can be executed locally or in a CI/CD pipeline. A sample project demonstrating how this can be done is located in our GitHub repo here: https://github.com/Azure/logicapps/tree/master/LogicAppsSampleTestFramework
This post will first highlight the capabilities this provides, walk through how to get this sample project up and running, and then dive into the details of the provided sample.
Capabilities provided
- Write automated tests for end-to-end Logic Apps functionality.
- Fine-grained validation at the run and action levels.
- Tests can be checked into a git repo and run either locally or as part of CI/CD pipelines.
- Mocking capabilities for HTTP actions and Azure connectors.
- Configurability that allows tests to use different setting values from production.
Prerequisites
- The latest 3.x version of Azure Function Core Tools
- Dotnet Core 3.1 SDK
- Azurite
- Visual Studio 2019
Running the sample tests
- Open LogicAppsSampleTestFramework.sln in Visual Studio
- Build the solution.
- In the Test Explorer pane, three tests should be present
- Start Azurite
- Run the test cases
Anatomy of a test case
All three sample test cases can be found in TestCases/TestCases.cs. Starting with the first one, RequestResponse, it tests a simple http request-response workflow.
The class doing the heavy lifting is WorkflowTestHost, and we pass it a list of WorkflowTestInputs, which are the individual workflows definitions that we want to run. WorkflowTestHost creates a new temporary Logic Apps project folder, starts the Logic App by invoking Functions Core Tools (func.exe) on that folder, monitors the output to verify that the runtime starts up successfully, and handles cleaning up this temporary folder after the test case finishes.
After the runtime starts up, we can interact with it using REST APIs. We use them to get the trigger callback URL, start the workflow by sending a POST request to that URL, and when the run finishes, we get the run status and action histories for fine-grained validation.
The HttpAction and ApiConnectionAction test cases build upon the first example by adding mocking capabilities. HttpAction, as its name suggests, adds an HTTP action that sends a request to the URL “@appsetting(‘httpuri’)”, which tells the runtime to get the value from the httpuri app setting. To set this app setting in local development, we pass the WorkflowTestHost a localSettings parameter, in which we set the httpuri key-value-pair to a localhost endpoint, and this content is placed in a local.settings.json to be loaded at runtime.
In addition to using WorkflowTestHost, we also construct a MockHttpHost which is used for handling mocked responses. In the HttpAction test case, we set it to return a constant response, but logic can be added to mock more complex behavior.
The ApiConnectionAction test case is similar to the aforementioned HttpAction one, but it mocks the response from a managed connector instead. We pass WorkflowTestHost an additional connectionDetails parameter which gets saved to connections.json and contains details for an ARM API connection. Its connectionRuntimeUrl is set to "@appsetting(arm-connectionRuntimeUrl)" and in localSettings we specify that value to be a localhost endpoint, the same way as we did for the HttpAction test case. Using a MockHttpHost once more, we mock the response for the connector.
We hope this sample provides a helpful starting point for setting up unit tests for your Logic Apps, and as always, we will appreciate any feedback or suggestions that you may have.