@tooniez

Published

- 7 min read

Postman API Contract and Regression tests session

img of Postman API Contract and Regression tests session

This Postman Collection is private. Some details in this post are also anonymised.

Various Postman API Contract and Regression tests

Description

In this activity, I explore Megaport’s Location endpoint and add some basic API tests using Postman collection.

Write a Postman collection to test the endpoint with the provided information. Include any assumptions made during test script creation.

Used Postman Functions

Below list various postman functions used in this collection.

Test FunctionDescription
pm.test()Executes a test script and checks if the specified condition is true.
pm.expect()Asserts a value against an expected value using various comparison operators.
pm.response()Provides access to the response data and allows extracting specific values for further testing.
pm.environment()Provides access to the Postman environment variables for setting and getting values.
pm.globals()Provides access to the global variables for setting and getting values.

Prerequisites

Before using this collection, make sure you have the following:

  • Postman installed.
  • Megaport API client credentials (client ID and client secret).

How to Use

  1. Open Postman
  2. Import provided collection
  3. Replace client ID and client secret with your actual in the collection’s pre-request script
  4. Run the collection to see results

Variables

This collection uses the following variables.

NameTypeDescriptionValue
baseURLGlobalProduction URLhttps://api.megaport.com
accessTokenGlobalAccess Token for EndpointsAuto-generated by pre-request script
statusCollectionLocation StatusActive
metroCollectionMetro AreaBrisbane
marketEnabledCollectionMarketEnabled (Bool)False
mveVendorCollectionVendor NameVMware

Pre-request Access Token Script

The pre-request script is to automate the process of obtaining an access token from the Megaport authentication server using the client credentials grant

  • The script sends a POST request to Megaport’s token endpoint using client credentials.
  • It sets the necessary headers and request body parameters.
  • The response is logged to the console, and if successful, the access token is saved as a variable in the Postman environment.
pre-request accessToken script..
   // Set your credentials
var clientId = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
var clientSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

// Set the URL and request parameters
var url = 'https://xxx-xxx.megaport.com/oauth2/token'
var headers = {
	'Content-Type': 'application/x-www-form-urlencoded',
	Authorization: 'Basic ' + btoa(clientId + ':' + clientSecret)
}

// Set the request body
var body = {
	mode: 'urlencoded',
	urlencoded: [{ key: 'grant_type', value: 'client_credentials' }]
}

// Send the POST request
pm.sendRequest(
	{
		url: url,
		method: 'POST',
		header: headers,
		body: body,
		secure: true
	},
	function (err, res) {
		// Handle the error
		if (err) {
			console.error('Error:', err)
			return
		}

		// Handle the response
		console.log(res)

		// Extract and save accessToken as a variable
		var jsonResponse = res.json()
		if (jsonResponse && jsonResponse.access_token) {
			pm.environment.set('accessToken', jsonResponse.access_token)
			console.log('Access Token saved:', pm.environment.get('accessToken'))
		}
	}
)

Test Types

This collection demonstrates Contract and Regression Test Types examples. The table below describes various differences.

AspectContract API TestingRegression Testing
FocusContracts and agreements between services or APIsOverall application functionality and features
PurposeEnsure adherence to communication contractsIdentify and prevent regression (new defects)
ScopeLimited to interactions between specific servicesBroader, covering the entire application or modules
TimingOften during the development of individual servicesTypically after code changes, part of release cycle
CoverageSpecific contracts, request/response formatsComprehensive, various test cases for diverse features
Application StageDuring service/component developmentAfter code changes, part of the software release cycle
Primary ConcernCommunication protocols, data structuresStability and integrity of existing functionality

Regression Tests

Each request should contain tests that:

  • Assert that the response status code is 200 OK
  • Assert that the content type is application/json
  • Assert that the response body Data is not empty
  • Assert that the response time is less than 5 seconds
Postman general regression test..
   //Regression Tests

pm.test('Verify Response status code is 200', function () {
	pm.expect(pm.response.code).to.equal(200)
})

pm.test('Verify Response Content-Type is application/json', function () {
	pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json')
})

pm.test('Verify response time is less than 5 seconds', function () {
	const fiveSecondsMs = 5_000 // 5 seconds in milliseconds
	pm.expect(pm.response.responseTime).to.be.below(fiveSecondsMs)
})

pm.test('Verify Data array is present and contains at least one element', function () {
	const responseData = pm.response.json()

	pm.expect(responseData).to.have.property('data').that.is.an('array').and.not.empty
})

Contract Tests

Metro: Verifies filtering by metro location

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?metro=Brisbane
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • metro: Brisbane
  • Assert that the response body contains the expected metro information
  • Assert each location includes latitude and longitude details
Metro Filter Postman tests..
   //Contract Tests

pm.test('Verify Metro fields are non-empty strings', function () {
	const responseData = pm.response.json().data

	responseData.forEach(function (location) {
		pm.expect(location.metro)
			.to.be.a('string')
			.and.to.have.lengthOf.at.least(1, 'Metro should not be empty')
	})
})

pm.test('Verify each location includes latitude and longitude details', function () {
	pm.response.json().data.forEach(function (location) {
		pm.expect(location).to.have.property('latitude').that.is.a('number')
		pm.expect(location).to.have.property('longitude').that.is.a('number')
	})
})

LocationStatus: Verify filtering by location status and metro

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?locationStatus=Active&metro=Brisbane
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • locationStatus: Active
    • metro: Brisbane
  • Assert that the response body contains only locations with the specified status
LocationStatus Filter Postman test..
   //Contract Tests

pm.test('Verify Status is Active for each location', function () {
	const responseData = pm.response.json().data

	// const statusOptions = ["Extended", "Deployment", "Active", "New", "Restricted", "Expired"];
	const statusOptions = ['Active']

	statusOptions.forEach((option) => {
		pm.expect(responseData.every((location) => location.status.includes(option))).to.be.true
	})
})

MarketEnabled: Verify filtering by marketEnabled

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?locationStatus=Active&metro=Brisbane&marketEnabled=true
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • locationStatus: Active
    • metro: Brisbane
    • marketEnabled: true
  • Assert that the respomnse body contains only AU markets that are active
MarketEnabled AU Postman test..
   //Contract Tests

pm.test('Verify Market is equal to AU for each location', function () {
	const responseData = pm.response.json()

	responseData.data.forEach(function (location) {
		pm.expect(location.market).to.equal('AU')
	})
})

mveVendor: Verify filtering by MVE vendor

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?metro=London&mveVendor=VMware
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • metro: London
    • mveVendor: VMware
  • Assert that the response body contains only locations with the specified MVE vendor
  • Asserts MVE sizes return response
  • Assets MVE details return expected properties
MVE Vendor Filter Postman tests..
   //Contract Tests

pm.test('Verify MVE Vendor property to equal VMware for each location', function () {
	pm.response.json().data.forEach(function (location) {
		pm.expect(location.products.mve[0].vendor).to.equal('VMware')
	})
})

pm.test(
	"Verify each location's MVE sizes array returns available sizes or is empty if unavailable",
	function () {
		pm.response.json().data.forEach(function (location) {
			if (location.products.mve[0].sizes.length > 0) {
				pm.expect(location.products.mve[0].sizes).to.not.be.empty
			} else {
				pm.expect(location.products.mve[0].sizes).to.be.empty
			}
		})
	}
)

pm.test("Verify location's MVE details object returns all available properties", function () {
	pm.response.json().data.forEach(function (location) {
		location.products.mve[0].details.forEach(function (detail) {
			pm.expect(detail).to.have.property('size').that.is.a('string')
			pm.expect(detail).to.have.property('label').that.is.a('string')
			pm.expect(detail).to.have.property('cpuCoreCount').that.is.a('number')
			pm.expect(detail).to.have.property('bandwidthMbps').that.is.a('number')
			pm.expect(detail).to.have.property('ramGB').that.is.a('number')
		})
	})
})

VerifyLocationsJsonSchema: Verify Locations Endpoint Schema

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?metro=Brisbane
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • metro: Brisbane
  • Assert that the response body matches expected JSON Schema
Locations JSON Schema Postman test..
   // Test Megaport Location Response Shape with expected JSON Schema

const expectedSchema = {
	type: 'object',
	properties: {
		message: {
			type: 'string',
			description: 'List all public locations'
		},
		terms: {
			type: 'string',
			description:
				'This data is subject to the Acceptable Use Policy https://www.megaport.com/legal/acceptable-use-policy'
		},
		data: {
			type: 'array',
			items: {
				type: 'object',
				properties: {
					id: { type: 'integer' },
					name: { type: 'string' },
					campus: { type: 'string' },
					metro: { type: 'string' },
					country: { type: 'string' },
					siteCode: { type: 'string' },
					networkRegion: { type: 'string' },
					address: {
						type: 'object',
						properties: {
							street: { type: 'string' },
							suburb: { type: 'string' },
							city: { type: 'string' },
							state: { type: 'string' },
							country: { type: 'string' },
							postcode: { type: 'string' }
						}
					},
					dc: {
						type: 'object',
						properties: {
							id: { type: 'integer' },
							name: { type: 'string' }
						}
					},
					market: { type: 'string' },
					vRouterAvailable: { type: 'boolean' },
					liveDate: { type: 'integer' },
					status: { type: 'string' },
					longitude: { type: 'number' },
					latitude: { type: 'number' },
					products: {
						type: 'object',
						properties: {
							mcr: { type: 'boolean' },
							megaport: {
								type: 'array',
								items: { type: 'integer' }
							}
						}
					},
					ordering_message: { type: ['string', 'null'] },
					diversityZones: { type: 'object' }
				},
				required: [
					'id',
					'name',
					'campus',
					'metro',
					'country',
					'siteCode',
					'networkRegion',
					'address',
					'dc',
					'market',
					'vRouterAvailable',
					'liveDate',
					'status',
					'longitude',
					'latitude',
					'products',
					'ordering_message',
					'diversityZones'
				]
			}
		}
	},
	required: ['message', 'terms', 'data']
}

// Test that the response matches the expected schema using built-in schema verification
pm.test('Verify Locations response matches expected JSON schema', () => {
	pm.response.to.have.jsonSchema(expectedSchema)
})

VerifyLocationsContract: Verify Locations Contract Specifications

  • Send a GET request to the endpoint: https://api.megaport.com/v2/locations?metro=Brisbane
  • Set the following headers:
    • Content-Type: application/json
  • Set the following parameters:
    • metro: Brisbane
  • Asserts various Locations Endpoint specifications
    • Location properties
    • Address sub properties
    • DC sub properties
    • Property types
Locations Contract Postman tests..
   //Locations Contract Test Collection

pm.test('Verify expected properties are in Locations endpoint', function () {
	const data = pm.response.json()
	// Check the expected properties exist
	pm.expect(data.data[0]).to.have.property('id')
	pm.expect(data.data[0]).to.have.property('name')
	pm.expect(data.data[0]).to.have.property('campus')
	pm.expect(data.data[0]).to.have.property('metro')
	pm.expect(data.data[0]).to.have.property('country')
	pm.expect(data.data[0]).to.have.property('siteCode')
	pm.expect(data.data[0]).to.have.property('networkRegion')
	pm.expect(data.data[0]).to.have.property('address')
	pm.expect(data.data[0]).to.have.property('dc')
	pm.expect(data.data[0]).to.have.property('market')
	pm.expect(data.data[0]).to.have.property('vRouterAvailable')
	pm.expect(data.data[0]).to.have.property('liveDate')
	pm.expect(data.data[0]).to.have.property('status')
	pm.expect(data.data[0]).to.have.property('longitude')
	pm.expect(data.data[0]).to.have.property('latitude')
	pm.expect(data.data[0]).to.have.property('products')
	pm.expect(data.data[0]).to.have.property('ordering_message')
	pm.expect(data.data[0]).to.have.property('diversityZones')
})

pm.test('Verify Address sub-properties are in Locations endpoint', function () {
	const data = pm.response.json()
	// Check Address properties exist
	pm.expect(data.data[0].address).to.have.property('street')
	pm.expect(data.data[0].address).to.have.property('suburb')
	pm.expect(data.data[0].address).to.have.property('city')
	pm.expect(data.data[0].address).to.have.property('state')
	pm.expect(data.data[0].address).to.have.property('country')
	pm.expect(data.data[0].address).to.have.property('postcode')
})

pm.test('Verify DC sub-properties are in Locations endpoint', function () {
	const data = pm.response.json()
	// Check DC properties exist
	pm.expect(data.data[0].dc).to.have.property('id')
	pm.expect(data.data[0].dc).to.have.property('name')
})

pm.test('Verify value types in Locations endpoint', function () {
	const data = pm.response.json()

	// Check the values have the expected types
	pm.expect(data.data[0].id).to.be.a('number')
	pm.expect(data.data[0].name).to.be.a('string')
	pm.expect(data.data[0].campus).to.be.a('string')
	pm.expect(data.data[0].metro).to.be.a('string')
	pm.expect(data.data[0].country).to.be.a('string')
	pm.expect(data.data[0].siteCode).to.be.a('string')
	pm.expect(data.data[0].networkRegion).to.be.a('string')
	pm.expect(data.data[0].address).to.be.an('object')
	pm.expect(data.data[0].dc).to.be.an('object')
	pm.expect(data.data[0].market).to.be.a('string')
	pm.expect(data.data[0].vRouterAvailable).to.be.a('boolean')
	pm.expect(data.data[0].liveDate).to.be.a('number')
	pm.expect(data.data[0].status).to.be.a('string')
	pm.expect(data.data[0].longitude).to.be.a('number')
	pm.expect(data.data[0].latitude).to.be.a('number')
	pm.expect(data.data[0].products).to.be.an('object')
	pm.expect(data.data[0].ordering_message).to.be.null
	pm.expect(data.data[0].diversityZones).to.be.an('object')
})

Notes

  • Ensure that your Megaport API client credentials are correctly set in the script.
  • This collection is intended for educational purposes and may need adjustments based on specific requirements.