Postman: How to make multiple requests at the same time - post

I want to POST data from Postman Google Chrome extension.
I want to make 10 requests with different data and it should be at the same time.
Is it possible to do such in Postman?
If yes, can anyone explain to me how can this be achieved?

I guess there's no such feature in postman as to run concurrent tests.
If I were you, I would consider Apache jMeter, which is used exactly for such scenarios.
Regarding Postman, the only thing that could more or less meet your needs is - Postman Runner.
There you can specify the details:
number of iterations,
upload CSV file with data for different test runs, etc.
The runs won't be concurrent, only consecutive.
Do consider jMeter (you might like it).

Postman doesn't do that but you can run multiple curl requests asynchronously in Bash:
curl url1 & curl url2 & curl url3 & ...
Remember to add an & after each request which means that request should run as an async job.
Postman however can generate curl snippet for your request: https://learning.getpostman.com/docs/postman/sending_api_requests/generate_code_snippets/

I don't know if this question is still relevant, but there is such possibility in Postman now. They added it a few months ago.
All you need is create simple .js file and run it via node.js. It looks like this:
var path = require('path'),
async = require('async'), //https://www.npmjs.com/package/async
newman = require('newman'),
parametersForTestRun = {
collection: path.join(__dirname, 'postman_collection.json'), // your collection
environment: path.join(__dirname, 'postman_environment.json'), //your env
};
parallelCollectionRun = function(done) {
newman.run(parametersForTestRun, done);
};
// Runs the Postman sample collection thrice, in parallel.
async.parallel([
parallelCollectionRun,
parallelCollectionRun,
parallelCollectionRun
],
function(err, results) {
err && console.error(err);
results.forEach(function(result) {
var failures = result.run.failures;
console.info(failures.length ? JSON.stringify(failures.failures, null, 2) :
`${result.collection.name} ran successfully.`);
});
});
Then just run this .js file ('node fileName.js' in cmd).
More details here

Not sure if people are still looking for simple solutions to this, but you are able to run multiple instances of the "Collection Runner" in Postman. Just create a runner with some requests and click the "Run" button multiple times to bring up multiple instances.

Run all Collection in a folder in parallel:
'use strict';
global.Promise = require('bluebird');
const path = require('path');
const newman = Promise.promisifyAll(require('newman'));
const fs = Promise.promisifyAll(require('fs'));
const environment = 'postman_environment.json';
const FOLDER = path.join(__dirname, 'Collections_Folder');
let files = fs.readdirSync(FOLDER);
files = files.map(file=> path.join(FOLDER, file))
console.log(files);
Promise.map(files, file => {
return newman.runAsync({
collection: file, // your collection
environment: path.join(__dirname, environment), //your env
reporters: ['cli']
});
}, {
concurrency: 2
});

In postman's collection runner you can't make simultaneous asynchronous requests, so instead use Apache JMeter instead. It allows you to add multiple threads and add synchronizing timer to it

If you are only doing GET requests and you need another simple solution from within your Chrome browser, just install the "Open Multiple URLs" extension:
https://chrome.google.com/webstore/detail/open-multiple-urls/oifijhaokejakekmnjmphonojcfkpbbh?hl=en
I've just ran 1500 url's at once, did lag google a bit but it works.

The Runner option is now on the lower right side of the panel

If you need to generate more consecutive requests (instead of quick clicking SEND button). You can use Runner. Please note it is not true "parallel request" generator.
File->New Runner Tab
Now you can "drag and drop" your requests from Collection and than keep checked only request you would like to generate by a Runner setting 10 iterations (to generate 10 requests ) and delay for example to 0 (to make it as fast as possible).

Easiest way is to get => Google Chrome "TALEND API TESTER"
Go to help + type in Create Scenario
...or just go to this link => https://help.talend.com/r/en-US/Cloud/api-tester-user-guide/creating-scenario
I was able to send several POST API calls simultaneously.

You can use Fiddler with started traffic capture to record manual queries from Postman, then select them in Fiddler's sessions list as much as you want and replay (press R key) - they would run in parallel.
https://docs.telerik.com/fiddler/generate-traffic/tasks/resendrequest

You can run multiple instances of postman Runner and run the same collection with different data files in each instance.

Open multiple postman. It replicates it and run concurrently.

Related

NestJS microservices error with "No matching message handler"

I'm building an application with microservices communicating through RabbitMQ (request-response pattern). Everything works fine but still I have a problem with error "There is no matching message handler defined in the remote service." - When I send POST to my Client app, it should simply send the message with data through client (ClientProxy) and the Consumer app should response. This functionality actually works, but always only for the second time. I know it sounds strange but on my first POST request there is always the error from Client and my every second POST request works. However this problem is everywhere in my whole application, so the particular POST request is just for the example.
Here is the code:
Client:
#Post('devices')
async pushDevices(
#Body(new ParseArrayPipe({ items: DeviceDto }))
devices: DeviceDto[]
) {
this.logger.log('Devices received');
return this.client.send(NEW_DEVICES_RECEIVED, devices)
}
Consumer:
#MessagePattern(NEW_DEVICES_RECEIVED)
async pushDevices(#Payload() devices: any, #Ctx() context: RmqContext) {
console.log('RECEIVED DEVICES');
console.log(devices);
const channel = context.getChannelRef();
const originalMsg = context.getMessage();
channel.ack(originalMsg);
return 'ANSWER';
}
Client has the RMQ settings with queueOptions: {durable: true} and the consumer as well queueOptions: {durable: true} with noAck: false
Please do you have any ideas what may causes the problem? I have tried sending the data with JSON.stringify and changing the message structure to {data: devices} but the error is still there.
I had same error and finally solve it today.
In my project, there is an api-gateway as a hybrid application to receive requests and pass data to other systems, every second request gives an error like below.
error: There is no matching message handler defined in the remote service.
Then I tried to remove the api-gateway hybrid application scope in the code below, the error is gone, hope this helps you out with this.
// api-gateway main.ts
const app = await NestFactory.create(AppModule);
// run as a hybrid app —→ remove it
app.connectMicroservice({
transport: Transport.RMQ,
noACK: false,
options: {
urls: [`amqp://${rmqUser}:${rmqPassword}#127.0.0.1:5672`],
queue: 'main_queue',
queueOptions: {
durable: false,
},
},
});
// run hybrid app
await app.startAllMicroservices(); —→ remove it
await app.listen(3000);
I solved this issue by placing the #EventPattern decorator on to a #Controller decorator method
I had this error while NOT using RabbitMQ. I found very little help online around this error message outside of it being related to RabbitMQ.
For me it was an issue where I was importing a DTO from another microservice in my microservice's Controller. I had a new DTO in my microservice that has a similar name to one in another microservice. I accidentally selected the wrong one from the automated list.
Since there wasn't any real indicator that my build was bad, just this error, I wanted to share in case others made the same mistake I did.
I encountered this same issue today and could not find any solution online and stumbled upon your question. I solved it in a hacky way and am not sure how it will behave when the application scales.
I basically added one #EventPattern (#MessagePattern in your case) in the controller of the producer microservice itself. And I called the client.emit() function twice.
So essentially the first time it gets consumed by the function that is in the producer itself and the second emit actually goes to the actual consumer.
This way only one POST call is sufficient.
Producer Controller:
#EventPattern('video-uploaded')
async test() {
return 1;
}
Producer client :
async publishEvent(data: VideosDto) {
this.client.emit('video-uploaded', data);
this.client.emit('video-uploaded', data);
}
I've experienced the same error in my another project and after some research I've found out that problem is in the way of distributing messages in RabbitMQ - named round-robin. In my first project I've solved the issue by creating a second queue, in my second project I'm using the package #golevelup/nestjs-rabbitmq instead of default NestJS library, as it is much more configurable. I recommend reading this question

Front-end testing using React and Selenium-Webdriver with Rails as Backend

I just want to test the Front-End part. So, here is my problem:
Background
I have a robust Ruby on Rails (V3.2) backend app and an entiry new and separate front-end app with ReactJs (V16.4).
Problem
We begin to test React app with the help of Selenium-Webdriver and JestJs, we managed to try several views, but the problem arose when we made POST requests to the rails API.
I don't want to fill my database (development) with garbage because of the tests.
Ex: What happens when I want to test the creation of a new user?.
Possible solutions thought
I was thinking in 3 solutions:
Intercept the API calls and mock them by imitating their response (ex: at submitting click using selenium-webdriver).
Make use of Rails test environment through React
Just revert the call of the API doing the opposite, this would mean creating often undesirable actions in the controller. (ex: doing a delete for each post)
It depends if you want to test the whole stack (frontend/backend) or only the frontend part.
Frontend tests
If you only want to test the frontend part go with your first solution : mock API calls.
You will be limited if you just use the selenium-webdriver directly. I would recommend using nightwatch or testcafe. Testcafe does not depend on selenium. This is also optional in the latest versions of Nightwatch.
Testcafe includes a Request mocking API : http://devexpress.github.io/testcafe/documentation/test-api/intercepting-http-requests/mocking-http-responses.html
With Nightwatch you could use nock. See Nightwatch Mock HTTP Requests
Full stack tests
If you want to test the whole stack, you may use this approach : implement a custom API endpoint to allow for resetting your database in a clean state before or after tests execution. (like "/myapi/clean")
You should disable access to this endpoint in production environments.
You can then implement test hooks (before/after) to call your custom api endpoint :
http://nightwatchjs.org/guide#using-before-each-and-after-each-hooks
http://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#test-hooks
You could have a test environment. From my experience, garbage data generated by tests is not such a big deal. You can periodically clean it up. Or you can spin up a new environment for every test run.
Finally I decided to use enzyme with jest and sinon.
example code:
import { mount } from "enzyme";
import sinon from "sinon";
beforeAll(() => {
server = sinon.fakeServer.create();
const initialState = {
example: ExampleData,
auth: AuthData
};
wrapper = mount(
<Root initialState={initialState}>
<ExampleContainer />
</Root>
);
});
it("example description", () => {
server.respondWith("POST", "/api/v1/example", [
200,
{ "Content-Type": "application/json" },
'message: "Example message OK"'
]);
server.respond();
expect(wrapper.find(".response").text().to.equal('Example message OK');
})
In the code above we can see how to intercept API calls using the test DOM created by the enzyme and then mock API responses using sinon.

Maintaining oath callback URLs

I'm developing a Loopback-based NodeJS app that uses GitHub Passport auth. For my development, I use localhost in my callbackURL setting in providers.json, but I have to change it to the published URL every time I deploy. At the same time, I have to change the same setting on GitHub.
How do you handle such scenarios? Is it possible to put a setting in providers.json? Is it possible to use two applications on GitHub and switch between them?
Probably you are loading the providers.json file in your server.js like in documentation: (https://loopback.io/doc/en/lb3/Configuring-providers.json.html)
var config = {};
try {
config = require('../providers.json');
} catch (err) {
console.trace(err);
process.exit(1); // fatal
}
So you can create two separate providers.json files (e.g. providers.dev.json providers.prod.json) and load a proper one according to e.g. NODE_ENV environment variable

Post request not working

i've got an android app and a really simple web service that make an insert in a DB with 3 values.
the titanium code is most like the example given on the docs
var xhr = Ti.Network.createHTTPClient();
xhr.onload = function(e) {};
xhr.open('POST','http://www.micheleantonaci.altervista.org/test/foobar.php');
xhr.send({
"latitude":00100,
"longitude":10000,
"type":'From Nexus'
});
and the web service is just
<?php
$con=mysql_connect('http://www.micheleantonaci.altervista.org/','***','***');
mysql_select_db('***',$con);
if(isset($_REQUEST['submit']))
{
$latitude=$_POST['latitude'];
$longitude=$_POST['longitude'];
$kind=$_POST['type'];
$sql="insert into foobar (latitude,longitude,type) values ('$latitude','$longitude','$kind')";
$res=mysql_query($sql) or die (mysql_error());
}
?>
now, when i try the webservice giving the values with the browser it works good, but with the app I get no results at all, any suggestions? tha app doesn't crash or log any error
You must use PHP function json_decode to get values.
Try adding the header like this:
xhr.setRequestHeader("Content-Type", "application/json");
You should also do a var_dump($_POST) in your PHP to see what's in it, not sure you'll get your stuff in separated variables...
When I see a problem like this, I setup 'Charles' or a similar proxy and have the device send it's request through the proxy. Then you can see if the device is send what is expected.
You could also try
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
The code is right, the problem was on the framework itself, at that day the post method wasn't working.
Nowadays it has been fixed.

Modify URL before loading page in firefox

I want to prefix URLs which match my patterns. When I open a new tab in Firefox and enter a matching URL the page should not be loaded normally, the URL should first be modified and then loading the page should start.
Is it possible to modify an URL through a Mozilla Firefox Addon before the page starts loading?
Browsing the HTTPS Everywhere add-on suggests the following steps:
Register an observer for the "http-on-modify-request" observer topic with nsIObserverService
Proceed if the subject of your observer notification is an instance of nsIHttpChannel and subject.URI.spec (the URL) matches your criteria
Create a new nsIStandardURL
Create a new nsIHttpChannel
Replace the old channel with the new. The code for doing this in HTTPS Everywhere is quite dense and probably much more than you need. I'd suggest starting with chrome/content/IOUtils.js.
Note that you should register a single "http-on-modify-request" observer for your entire application, which means you should put it in an XPCOM component (see HTTPS Everywhere for an example).
The following articles do not solve your problem directly, but they do contain a lot of sample code that you might find helpful:
https://developer.mozilla.org/en/Setting_HTTP_request_headers
https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads
Thanks to Iwburk, I have been able to do this.
We can do this my overriding the nsiHttpChannel with a new one, doing this is slightly complicated but luckily the add-on https-everywhere implements this to force a https connection.
https-everywhere's source code is available here
Most of the code needed for this is in the files
IO Util.js
ChannelReplacement.js
We can work with the above files alone provided we have the basic variables like Cc,Ci set up and the function xpcom_generateQI defined.
var httpRequestObserver =
{
observe: function(subject, topic, data) {
if (topic == "http-on-modify-request") {
var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
var requestURL = subject.URI.spec;
if(isToBeReplaced(requestURL)) {
var newURL = getURL(requestURL);
ChannelReplacement.runWhenPending(subject, function() {
var cr = new ChannelReplacement(subject, ch);
cr.replace(true,null);
cr.open();
});
}
}
},
get observerService() {
return Components.classes["#mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
},
register: function() {
this.observerService.addObserver(this, "http-on-modify-request", false);
},
unregister: function() {
this.observerService.removeObserver(this, "http-on-modify-request");
}
};
httpRequestObserver.register();
The code will replace the request not redirect.
While I have tested the above code well enough, I am not sure about its implementation. As far I can make out, it copies all the attributes of the requested channel and sets them to the channel to be overridden. After which somehow the output requested by original request is supplied using the new channel.
P.S. I had seen a SO post in which this approach was suggested.
You could listen for the page load event or maybe the DOMContentLoaded event instead. Or you can make an nsIURIContentListener but that's probably more complicated.
Is it possible to modify an URL through a Mozilla Firefox Addon before the page starts loading?
YES it is possible.
Use page-mod of the Addon-SDK by setting contentScriptWhen: "start"
Then after completely preventing the document from getting parsed you can either
fetch a different document from the same domain and inject it in the page.
after some document.URL processing do a location.replace() call
Here is an example of doing 1. https://stackoverflow.com/a/36097573/6085033

Resources