Newman – Map over promises concurrently

Newman for Postman collections is simply amazing.


And what about if I got a lot of collections to run and want them to run in parallell with a desired level amount?

After many trials, I got finally my personal solution that I would like to share with you.

I jumped into this beautiful package named p-map

Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently.
This is different from Promise.all() in that you can control the concurrency and also decide whether or not to stop iterating when there’s an error.

and using it combined with the newman.run call from the library provided it works very well!

First of all, you need to create an array of params (one for each collection) to be passed to each newman.run to execute. You can see that in this example, I also set environment to use, iterationCount, some envVar and the reporters (in particular you could see one of my personal best choice for detailed report -> newman-reporter-htmlextra)

let fullTests= [];
fs.readdirSync(collectionDirectory).forEach((collection) => {
  fullTests.push(collectionDirectory + collection);
});

const paramsRun = []
for (let i = 0; i < fullTests.length; i++) {

	let collectionName = String(fullTests[i]).replace(/^.*[\\\/]/, '');

	paramsRun.push({
		collectionName: collectionName,
		newmanParams : {
			insecure: true,
			collection: path.join(__dirname, String(fullTests[i])),
			environment: path.join(__dirname, String(env)),
			iterationCount: parseInt(ITERATION_COUNT,10),
			silent: true,
			envVar: [
				{'key':'bffMainVersion', 'value': bffMainVersion}
			],
			reporters: ['htmlextra','cli','junit'],
			reporter: {
				htmlextra: {
					export: dirLogs + '\\HtmlExtra_Results\\' + currentEnv + '_Report_' + collectionName + '.html',
					browserTitle: collectionName,
					title: collectionName,
					showOnlyFails: true,
					timezone: 'Europe/Rome'
				},
				junit: {
					export: dirLogs + '\\JUnit_Results\\MW_SwitchPage_' + currentEnv + '_Report_' + collectionName.substring(0,collectionName.indexOf('.')) + '.xml'
				}
			}
		}
	})
}

After that, you need to specify the mapper, that takes in each of the params declared before and assign them to the newman.run execution

const mapper = async paramRun => {
	console.info("Start run for " + paramRun.collectionName + "...")
	return await new Promise(function (resolve) {
		newman.run(paramRun.newmanParams, function (err) {
			if (err) { throw err; }
			resolve(true);
		});
	})
}

And now the magic : with the pMap command, you can easly start the Newman executions with the desired level of parallelism, passed throught the concurrency key

await pMap(paramsRun, mapper, { concurrency: parseInt(PARALLEL_RUN_COUNT) })