We have a lot of API level automated tests written as collections of requests in Postman.
We have a script to run all collections in automated manner.
Is there a way to label/run only subset of requests e.g. with some label e.g. as smoke suite, without copying requests to new collection(s) and run then explicitly (as this yields the need to maintain same tests in 2 places...)?
There might be labels, groups or some script that skips the request is env variable is set...
you can create folders and organize test like
smoke_and_regression
smoke_only etc
you can specify which folder to run using --folder arguent when using newman as command line tool
you can also control the execution flow using postman.setNextRequest .
and also you can run newman as an npm module.
you just need to write a logic to read the collection file and get all folder names containing "smoke" for eg and pass it as an array
const newman = require('newman'); // require newman in your project
// call newman.run to pass `options` object and wait for callback
newman.run({
collection: require('./sample-collection.json'),
reporters: 'cli',
folder: folders
}, function (err) {
if (err) { throw err; }
console.log('collection run complete!');
});
Just update for the comments:
in old and new UI you can select which folder to execute in collection runner
Get all requests in the collection:
you can also get information about all the requests in a collection by using :
https://api.getpostman.com/collections/{{collection_UUID}}
to get uuid and api key goto :
https://app.getpostman.com
Now for generating api key >
goto account settings > api key and generate api key.
to get collection uuid goto specific workspace and collection and copy the uuid part from url:
Now in your collection
Rename all requests as:
get user details [Regression][Smoke][Somethingelse]
get account details [Regression]
Then Create a new request called initial request and keep it as the first request in your collection:
url: https://api.getpostman.com/collections/8xxxxtheuuidyoucopied
authorization: apikey-header : key: X-Api-Key and value: yourapikey
test-script :
pm.environment.unset("requestToRun")
reqeustlist = pm.response.json().collection.item.map((a) => a.name)
requestToRun = reqeustlist.filter((a) => a.includes(pm.environment.get("tag")))
let val = requestToRun.pop()
pm.environment.set("requestToRun", requestToRun)
val ? postman.setNextRequest(val) : postman.setNextRequest(null)
Now set the envirnoment variable as what you want to look for eg: run script that contains text "Regression" then set pm.environment.set("tag","Regression")
Now in your collection-pre-request add:
if (pm.info.requestName !== "initial request") {
let requestToRun = pm.environment.get("requestToRun")
let val = requestToRun.pop()
pm.environment.set("requestToRun", requestToRun)
val ? postman.setNextRequest(val) : postman.setNextRequest(null)
}
Output:
Example collection:
https://www.getpostman.com/collections/73e771fe61f7781f8598
Ran only reqeusts that has "Copy" in its name
Related
I want to make a postman request that returns a list of IDs.
The returned list can contain 1 or multiple IDs.
In tests section i want to use these returned IDs to make new requests.
Is it possible to send requests from tests section in for loop and check their returned data BEFORE sending another request?
I tried using simple for loop and pm.sendRequest but due to async this did not work.
Is this possible using Postman?
You can achieve that by using postman.setNextRequest("request_name")
For example:
Request 1: Tab Tests Get the ids and save ids to environment
pm.environment.set("ids", JSON.stringify(pm.response.json().ids));
Request 2:
Tab Pre-req
let ids = JSON.parse(pm.environment.get("ids"));
if(ids.length > 0){
let id = ids.shift();
pm.environment.set("ids", JSON.stringify(ids));
pm.variables.set("id", id);
}
Tab Tests
let ids = JSON.parse(pm.environment.get("ids"));
if(ids.length > 0){
postman.setNextRequest("Req2");
}
Result:
I'm trying to use postman for some basic API security tests and I have this URL:
http://example.com/api/v1/users/{{userID}}
{{userID}} is set to some user on site, and I want to set three tests that check if request is valid, if request has IDOR and if request has SQL injection.
This is the idea:
// userID is set to 20 ( valid user )
pm.test("Initial valid request", function () {
pm.expect(pm.response.text()).to.include("Peter"); });
*CHANGE THE VALUE OF {{userID}} to 30 to test for IDOR*
* URL should be set to http://example.com/api/v1/users/30 *
pm.test("IDOR protection valid", function () {
pm.expect(pm.response.text()).to.include("User not found."); });
*CHANGE THE VALUE OF {{userID}} to 20'or'1 to test for SQL injection*
* URL should be set to http://example.com/api/v1/users/20'or'1 *
pm.test("SQL injection test", function () {
pm.expect(pm.response.text()).to.include("You have an error"); });
My question is how do I change the values of {{userID}} so that next request uses changed value and not the one from environment variables.
Thanks
From the docs:
Tests will execute after the request runs
So each test will run based on the one request. So doing something like the following in your test
pm.collectionVariables.set('userID', 'IDOR*')
// or
pm.variables.set('userID', 'IDOR*')
Won't have the effect you're after as it doesn't make a request per test.
One potential way to solve this would be to have multiple requests, all of which have set the different variable values in the Pre-request Script. As an example, you might have a request that looks like this:
And then the related test:
I've got a PATCH request that looks like this:
{{host}}/api/invoice/12345678/withdraw
host is a variable determining the environment.
For this request I need to add a unique authorization token.
The problem is I need to send dozens of such requests. Two things change for each request:
id of invoice (for this case is '12345678')
auth token (herebetoken1).
How can I automate it?
You can use Postman Runner for your problem. In Runner, you can send specified requests in specified iterations and delay with data (json or csv file).
For more info, I suggest you take a look at the links below.
Importing Data Files in Postman
Using CSV and JSON Data Files
Request:
Runner:
Data: (You can choose one of them)
Json Data: (data.json)
csv Data: (data.csv)
Preview Data in Runner:
Result:
use the below pre-request script , and call replace id in url and auth in authorization with {{id}} and {{token}} variables . Use collection runner to execute it .
Replace the hashmap with what you requires
hashmap = {
"1234": "authtoken1",
"2222": "authtoken2"
}
pm.variables.get("count") === undefined ? pm.variables.set("count", 0) : null
let keyval = Object.entries(hashmap)
let count = pm.variables.get("count")
if (count < keyval.length) {
pm.variables.set("id", keyval[pm.variables.get("count")][0])
pm.variables.set("token", keyval[pm.variables.get("count")][1])
pm.variables.set("count", ++count)
keyval.length===count? null:postman.setNextRequest(pm.info.requestName)
}
Example collection:
https://www.getpostman.com/collections/43deac65a6de60ac46b3 , click inport and import by link
I'm writing test in Postman and I have multiple requests grouped like this:
Some test title:
Create a user (set of "pre-requests"):
sending a few requests required to create a user, necessary to run tests
Some action on a created user (here I'm testing what is in the test title)
one or more requests
Another test title:
Create a user (set of "pre-requests", the same as in test 1.):
sending a few requests required to create a user, necessary to run tests
Some action on a created user (not related ot test 1.)
one or more requests
To summarize I need to create a user before every request when I want to test something.
My question - How can I re-use "Create a user" set of requests without copying it?
This is how you can re-use the set of requests in pre-testcases and Test by setting environment variable and call it using eval function
pre-test case -
var Create_a_user = () => {
pm.sendRequest("http://mocktarget.apigee.net/json", function(err, res) {
tests["Status code is 200"] = pm.expect(res).to.have.property('code', 200);
console.log('firstName',res.json().firstName);
});
pm.sendRequest("http://mocktarget.apigee.net/json", function(err, res) {
tests["Status code is 200"] = pm.expect(res).to.have.property('code', 200);
console.log("lastName - "+ res.json().lastName);
});
pm.sendRequest("http://mocktarget.apigee.net/json", function(err, res) {
tests["Status code is 200"] = res.code === 200;
console.log("city - "+ res.json().lastName.city);
});
};
pm.environment.set("Create_a_user", Create_a_user.toString());
Test -
eval(pm.environment.get("Create_a_user"))();
output -
firstName - John
lastName - Doe
city - San Jose
Disclaimer -
Use Eval function carefully, it may fizzled up your code or its execution.
If i'm understanding correctly what you want is unfortunately not currently supported. I've been waiting on this feature a while myself.
https://github.com/postmanlabs/postman-app-support/issues/1535
I have a Collection that has three endpoints. The first one creates an asset, the second one adds a file to the asset, and the third one lists all the assets.
How can I run the second one, the one that adds a file to the asset, more than once per each iteration of the Runner?
I'd like the test to create an asset and add multiple files to it for each iteration.
Any suggestions? I know I can duplicate the endpoint, but I was wondering if there was a programmatic way to do it.
Create 2 environment variables:
"Counter" (Number of times you want the request to run)
"RequestNumber" = 1 (To track the current request number)
Add this code to the test section of the request you want to run multiple times:
const counter = pm.environment.get("Counter");
const requestNumber = pm.environment.get("RequestNumber") || 1;
if (requestNumber < counter) {
postman.setNextRequest("RequestName");
requestNumber ++;
pm.environment.set("RequestNumber", requestNumber);
}
else {
pm.environment.set("RequestNumber", 1);
}
Instead of using postman.setNextRequest(), a bit cleaner way to hit the same endpoint is to use pm.sendRequest().
In Test or Pre-request Script, you can create a request object that would describe the request you want to send (URL, HTTP method, headers body, etc.) and put it in pm.sendRequest() function.
Consider:
const requestObject = {
url: 'https://postman-echo.com/post',
method: 'POST',
header: 'headername1:value1',
body: {
mode: 'raw',
raw: JSON.stringify({ key: "this is json" })
}
}
pm.sendRequest(requestObject, (err, res) => {
console.log(res);
});
To run the same request multiple times just put the function in for/for..in/for..of/forEach loop.
Consider:
for(let iteration = 0; iteration < 5; iteration++) {
pm.sendRequest(requestObject, (err, res) => {
console.log(res);
});
}
If you want you can modify the requestObject inside your loop.
Check out the Postman Documentation for more details.
So far, there is no straight forward solution using Postman, to configure several hits for the same request within a folder/collection.
Nevertheless, you can write some code in Pre-request script section, by adding a counter with number of hits you want and call postman.setNextRequest("request_name") method (read more about it from here) with you current request.
Out of Postman app scope, you can export your collection (as JSON file) and write some javascript code using newman which is a Command-line companion utility for Postman (more about newman from here) which gets a run method with a lot of iteration count and data options that would help you (for example, putting your second request in folder and iterates through it).
Hope that helps!