Friday Fact: You can use Bruno collections inside CI/CD Pipelines to do unit tests in your API Management APIs

  • João Ferreira
  • Jun 12, 2026
  • 4 min read

Testing APIs is crucial for ensuring applications behave as expected. In particular, when working with Azure API Management (APIM), validating APIs early helps prevent issues later in the delivery process. Fortunately, there is a great open-source alternative to Postman that makes this even easier — Bruno.

Unlike Postman, Bruno stores collections as plain .bru files directly on disk. As a result, your test collections live inside your Git repository alongside your code, making them natively version-controlled and fully auditable through pull requests.

📝 One-Minute Brief

Automating API testing is critical for delivering reliable applications. This article explains how to use Bruno, an open-source alternative to Postman, to test Azure API Management (APIM) APIs. By exporting APIs as OpenAPI specifications and importing them into Bruno, teams can create version-controlled test collections using .bru files stored in Git. Combined with Bruno CLI and Azure Pipelines, this approach enables automated API validation during CI/CD, improves collaboration, and ensures faster feedback cycles while keeping secrets secure.

Setting Up Bruno with APIM

Since APIM does not have a native “Export to Bruno” option, the process begins by exporting the API as OpenAPI and manually building the collection. This only needs to be done once.

To get started, you need to:

  • Access the Azure Portal and go to your Azure API Management instance.
  • On the API Management instance, choose the API you want to test from the APIs section.
  • Click the (3 dots) next to the API, then click Export.
APIs
  • On the Export panel, select OpenAPI v3 (JSON or YAML) and save the file.
Download definition
  • Open Bruno, create a new collection, and import the OpenAPI file. Bruno will generate one .bru file per endpoint automatically.
Bruno Workspace
Import collection

Once imported, you can start sending requests to the API endpoints directly from Bruno. This approach makes it easier to test operations such as GET, POST, PUT, and DELETE. As a result, you can validate API behavior quickly and consistently during development.

Adding Tests to Your Collection

Each .bru file supports a tests block written in JavaScript, where you can assert status codes, response times, headers, and body content. For example, a simple GET test looks like this:

test("Status is 200", function() {
  expect(res.status).to.equal(200);
});

test("Response time is acceptable", function() {
  expect(res.responseTime).to.be.below(3000);
});

test("Response is JSON", function() {
  expect(res.headers["content-type"]).to.include("application/json");
});

By writing tests this way, developers can verify API functionality without manually inspecting responses. Consequently, testing and troubleshooting become faster and more efficient. In addition, teams can detect issues early and reduce the feedback loop.

Tests status

Handling the APIM Subscription Key

APIM requires a subscription key to authenticate requests. Bruno handles this cleanly through environment files. The key is defined as a blank placeholder in a committed dev.bru environment file and injected at runtime — never stored in the repository.

vars {
  baseUrl: https://your-apim-name.azure-api.net
  subscriptionKey:
}

The actual key value is stored as a secret variable in Azure Pipelines and passed to the Bruno CLI at runtime using the --env-var flag.

Running Bruno Inside Azure Pipelines

You can run the same Bruno collection inside Azure Pipelines. In this scenario, the pipeline automatically tests APIs as part of the CI/CD process. Therefore, each deployment validates API functionality before new code reaches production.

- script: npm install -g @usebruno/cli
  displayName: "Install Bruno CLI"

- script: |
    cd ./bruno-tests
    bru run \
      --env dev \
      --env-var subscriptionKey=$APIM_KEY \
      --output ../test-results.xml \
      --format junit
  displayName: "Run Bruno Tests"
  env:
    APIM_KEY: $(apimSubscriptionKey)

- task: PublishTestResults@2
  inputs:
    testResultsFormat: "JUnit"
    testResultsFiles: "test-results.xml"
  displayName: "Publish Test Results"
  condition: always()

The test results are published directly into Azure DevOps, giving the team a clear pass/fail summary for every pipeline run. If you followed every step/rule, the end result of a very simple DevOps repository with Bruno testing should look like this:

Azure DevOps

We have mentioned “dev.bru,” which contains the variables, and “get-items.bru,” which contains the tests. We are now just missing “bruno.json”. This file tells Bruno that a folder is a collection. Without it, Bruno won’t recognize the folder at all. Here is our example:

{
  "version": "1",
  "name": "APIM Tests",
  "type": "collection",
  "ignore": []
}

Now, if you run the Azure Pipeline with the script given by us, you should get the results of your tests!

Bruno Tests

To lazy to read? We’ve got you covered! Check out our video version of this content!

Hope you find this helpful! If you enjoyed the content or found it useful and wish to support our efforts to create more, you can contribute towards purchasing a Sauron’s Action Figure for Sandro’s son, yep, not for me! 

Buy me a coffee
Author: João Ferreira

João Ferreira is a Enterprise Integration Consultant at DevScope

Leave a Reply

Your email address will not be published. Required fields are marked *

The Ultimate Cloud
Management Platform for Azure

Supercharge your Azure Cost Saving

Learn More
Turbo360 Widget

Back to Top