Testing Azure Functions on Azure DevOps
Today we’re going to talk a bit about testing strategies for Azure Functions. We'll see how to build and setup the testing framework for our Azure Functions.
Join the DZone community and get the full member experience.Join For Free
Hi All! Today we’re going to talk a bit about testing strategies for Azure Functions. We’ll see how setup our test framework and in another article, we’ll see how to create a build pipeline on Azure DevOps.
As part of my daily job, I’m spending a lot of time working with Azure and Azure Functions. These days I’m also working a lot with Durable Entities, which open the door to even more scenarios. Anyways, no matter what’s the technology behind, one of the best ways to ensure that our software is reliable is to add automatic tests. And these tests have to be part of the build pipeline.
Now, based on my researches so far, we can’t create a Functions Host directly as we could do for a “regular” WebAPI. What we can do instead is make use of the Azure Function Core Tools and manually (aka via code) spin up the host in an XUnit Fixture.
This has the only drawback that when running the tests locally we won’t be able to debug the Function code. However, keep in mind the goal here: we want to test the boundaries of our services by probing the various Function Triggers.
And this is a form of Black Box Testing: we’re not supposed to know what’s inside the box, only how to operate it.
If we need to debug, we can always run the Function project directly from VS and check the behaviour via Postman (if it’s a REST endpoint). Just sayin’.
Moreover, as stated before, we will be executing those tests in our build pipeline, so debugging is not our primary interest.
Anyways, let’s just into the code! The first thing to do, assuming we already have an Azure Functions project, is to create the Test project, add a reference to XUnit and create a Fixture:
As you can see, in the cTor we’re reading a few values from the configuration:
- the path to dotnet.exe
- the path to func.dll from the Azure Functions Core Tools
- the path to our Azure Functions DLL
- the port we want to use to expose the host
The Process class will be basically running something like:
from the bin\Debug (or Release) directory of our Azure Functions project.
We’re also creating and publicly exposing an HttpClient: our tests will be using it to “talk” with the Functions Host. To keep things simple, I’m assuming that we’re using only HTTP Triggers.
As some of you might have noticed, the Fixture class is also implementing IDisposable, to properly dispose of the Process and of the HttpClient:
The next thing to do is to create our test class as usual. Now, it’s quite likely that we might want to split our tests into multiple classes.
In this case, we have to make sure to not spin up more than one Functions Host.
Luckily, XUnit comes to the rescue with Collection Fixtures. All we have to do is to create an empty class and mark it with the CollectionDefinition attribute:
Now we can decorate our test classes with all the necessary attributes and inject the Fixture:
That’s all for today! Next time we’ll push our Azure Functions to the repository and make sure the build pipeline runs fine. Ciao!
Opinions expressed by DZone contributors are their own.