A unit testing framework for Microsoft Azure resources, written in NodeJS and TypeScript. Designed to test any Azure cloud environment with ARM-based resources.
AzUnit authenticates with Azure and accesses a subscription, downloading the JSON ARM template defining each resource. It then finds the latest API version for the relevant provider and resource type, and uses it to download the full JSON definition for the resource.
Tests comprise a series of JsonPath-based assertions to validate the properties of the resources. Code coverage tracks which resources have assertions run against them, and provides coverage level as a percentage.
For feature roadmaps, please refer to the GitHub projects associated with this repository.
First, install AzUnit using NPM:
npm install -g azunit
Then, navigate to an empty directory and run:
azunit init
This will populate a sample project structure; refer to the command reference for further information.
Then create some JS files to run the tests. Call the global function start
passing a test title, and provide a function to test your resources. When creating tests, a productive workflow is often to sign in to Microsoft Resource Explorer and navigate to the resources you want to test. Find the properties you are interested in, and write tests to validate them.
title("website.com");
start("Search Service", (test) => {
var search = test.selectResourcesByName("someservice");
search.shouldHaveInstanceCount.equals(1);
// Test ARM properties using JsonPath in a fluent API. Each assertion
// is run against the selected resource(s).
search.shouldHaveProperty("$.location").as("Location").equals("West Europe");
search.shouldHaveProperty("$.sku.name").as("Service Tier").equals("basic");
test.log.trace("An example trace message");
test.log.write("An example log message");
test.log.warning("An example warning message");
test.log.error("An example error message");
var storage = test.selectResourcesByName("nk1b1234a2d3401x46fee9aa");
storage.shouldHaveProperty("$.properties.encryption.services.file.enabled").as("File encryption").disabled();
});
To run your test you will need to create a Service Principal and assign it Reader permissions on the Azure Subscription(s) that you want to test. Full instructions can be found here.
Finally, run AzUnit from shell passing details of the Service Principal, Tenant, and Subscrpition as parameters. You can call AzUnit multiple times for each environment you want to test. There are two options for calling AzUnit: test
or run
.
Intended for use in terminal and allowing quick runs against different environments.
azunit test ./samples/quickstart/test.js \
--tenant acme.onmicrosoft.com \
--subscription ffffffff-ffff-ffff-ffff-ffffffffffff \
--app-id ffffffff-ffff-ffff-ffff-ffffffffffff \
--app-key [key] \
--output-xml .azunit/test.xml \
--run-name "My glorious test run"
Leverage YAML file configuration to pass the same configuration in a more reusable way, suitable for sharing with a wider team.
run:
name : Web farm tests
select : ./samples/quickstart/*.js
parameters : ./samples/quickstart/test.params.json
language : enGb
silent : false
auth:
tenant : $TENANT
appId : $APP_ID
appKey : $APP_KEY
subscription : $SUBSCRIPTION
coverage:
resources:
threshold : 90
fail : true
APR:
threshold : 1
fail : true
AAPR:
threshold : 1.2
fail : true
output:
json : .azunit/output.json
xml : .azunit/output.xml
Settings in the YAML file are as follows:
Setting | Description |
---|---|
run/name | A descriptive title for the run. |
run/select | Glob for defining test JS files to process. |
run/parameters | JSON data passed to JS files to enable test reuse. |
run/language | Language. Only enGb is currently supported. |
run/silent | Suppress console output (secure build scenarios?) |
auth/tenant | The tenant ID for the target subscription. |
auth/appId | The app ID with access to the subscription. |
auth/appKey | The app key to utilise this application. |
auth/subscription | The subscription ID. |
output/json | Path to store run results (in JSON format). |
output/xml | Path to store run results (in XML format). |
Note: All values starting with $
will be treated as environment variables and loaded appropriately. To avoid putting sensitive information in config files (which should be source controlled), set this information in local environment variables (on your dev machine or build pipeline) and reference the variable with the $ prefix (e.g. appKey: $KEY
)
Finally, run AzUnit from your shell passing the configuration file as a parameter:
azunit run --config azunit.dev.yml
This will result in output similar to that shown below:
AzUnit can be passed multiple commands, each of which has its own parameters.
Initialises a project in the current directory.
azunit init
The capability of init is reasonably limited at the moment: it simply creates files if they don't already exist, so it won't try to merge new additions to your .gitignore. Rather than running azunit init
in an existing directory, I recommend doing it in a clean one and then merging the relevant settings.
After running azunit init
, set up your environment with Service Principal Authentication, adding your settings to the .env
file or using actual environment variables on your machine.
Runs AzUnit with options configured in the specified YAML file.
azunit run --config azunit.yml
Parameter | Alias | Description | Default |
---|---|---|---|
--config | -c | String. Path to the YAML config file describing the environment. | None |
A command to enable AzUnit to run without YAML file configuration, executing the specified tests against the named environment. Multiple test files can be included and there are a reasonable number of options, but you don't get the extensive control of things like test coverage that you would get with a YAML config input.
azunit test ./test1.js ./test2.js [parameters]
Parameter | Alias | Description | Default |
---|---|---|---|
--tenant | -t | String. The domain name of the tenant, often ends in ".onmicrosoft.com". | None |
--app-id | -a | GUID. The service principal with access to the target subscription. | None |
--app-key | -k | String. The secret for the service principal. | None |
--subscription | -s | GUID. The ID of the subscription containing resources to tests. | None |
--run-culture | -c | Language code. Culture/language code for messages in the run. * | en-GB |
--run-name | -n | String. A name for the test run. | Current date |
--parameters | -p | String. Path to a file containing JSON data to be passed to test files. | None |
--silent | -x | No value required: prevents logging test result output to the console. | N/A |
--output-xml | -X | String. A filename to output the results of the run in XML format. | Based on date |
--output-json | -J | String. A filename to output the results of the run in JSON format. | Based on date |
* Run culture is currently ignored as the output only runs in a single culture: enGb
To use parameters, create a file containing a JSON data structure that you want to make available to your tests. For example, create env-test.params.json
containing:
{
"prefix": "tst"
}
You can use this parameter within your tests as follows (parameters will be in the global context):
start("Search Service", (test) => {
test.log.write(parameters.prefix);
});
This allows tests to be configured and reused across multiple environments.
This is a development tool that dumps an array of all the resources under test in a subscription. It can be used for debugging if particular JsonPath queries don't seem to be evaluating correctly, by dropping what AzUnit "sees" into a handy file for reference.
azunit dump --config azunit.yml --output dump.json
Parameter | Alias | Description | Default |
---|---|---|---|
--config | -c | String. Path to the YAML config file describing the environment. | None |
--output | -o | String. Name of a file to dump resource output to. | None |
Initially the project included output formats for CSV, HTML, and Markdown. These have been removed for several reasons:
- They required an amount of unnecessary package bloat
- Many decisions around formatting were arbitrary and probably wouldn't properly serve use cases
- Formatting outputs can be customised in test post-processing, for example:
- Running XSLT over the output from PowerShell
- Dropping into gulp
- Utilising a templating framework like Handlebars or Liquid
Samples of transforms that can serve as a basis for different projects can be found in samples/transforms
. Feel free to contribute new ones via a pull request, so long as they're generic, self-contained, and reasonably unique I'll be happy to include them.
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
Developer - Nathan Kitchen (@nathankitchen)
This project is Open Source and licensed under MIT.