Proxying API calls through Test'em #218

Closed
kevindente opened this Issue May 31, 2013 · 31 comments

Comments

Projects
None yet
7 participants
Contributor

kevindente commented May 31, 2013

We're trying to get an existing code base under test with Test'em. The code calls back to a REST API to do a bunch of its work (not as isolated as would be ideal but it is what it is for now). To get around the same origin policy restrictions I extended Test'em to support proxying API calls to another service. Is this something you'd be interested in pulling in? If so, I can submit a PR.

Collaborator

airportyh commented Jun 4, 2013

I am a little torn on this. On the one hand I had a few requests for this and I've even written code for it...on the other hand I don't think I should encourage people to use this approach - aside from the obvious problems (slow running tests, coupling to the backend), the setup just seems complicated to me. Unless there is a convincing argument I am going to pass on this.

airportyh closed this Jun 4, 2013

Contributor

kevindente commented Jun 4, 2013

:(

I agree that this approach isn't the goal, but when you're trying to get legacy code under test, it's sometimes the only option. The most convincing argument to me is that anything that gets people testing is good. Giving people a reason to avoiding writing tests is bad.

Not sure what you mean by "the setup seems complicated". It was actually very little code to implement a simple passthrough proxy (I used node-http-proxy).

If you won't considering adding the proxy as a native feature, would you consider adding an extensibility point that allows custom code to be injected in to the server processing? That way I could add the proxying support via my own custom extension.

Collaborator

airportyh commented Jun 5, 2013

Have you considered using a mock ajax library like sinon to test interactions? By complicated, I mean that not only do you have to configure testem to point to some endpoint, you also have to make sure that endpoint is running while you are running the tests - more dependencies, more points of possible failure.

Contributor

Raynos commented Aug 21, 2013

@airportyh this is an important feature for when you want to test javascript libraries that do HTTP or WebSockets, You need those integration tests.

Collaborator

airportyh commented Aug 22, 2013

Here's another approach airportyh#249, any thoughts on pros vs cons?

Contributor

Raynos commented Aug 22, 2013

@airportyh that might work but then I need my own html page.

Automated integration tests are really important to a lot of application teams. You could argue that service-level integration tests probably don't need to run in multiple browsers, and teams that are doing this kind of testing can do it via mocha or jasmine today, but then they'd have to configure testem and another framework if they want to use testem for their unit tests.

I'm also interested in using Testem as a vehicle to manage cross-browser functional testing, but I can't do anything along those lines without the proxy to let me talk to my web server.

Collaborator

airportyh commented Jan 31, 2014

@geekytime see this thread airportyh#337. I feel uncomfortable including a lot of features especially those which I don't use because I just don't have much man power. I am planning a plugin architecture for that reason - you can make it do whatever you want. But, if you need something before the architecture is in place, just fork testem.

Awesome! A plugin system would be fantastic, as then we'd have lots of flexible options for these kinds of things. I'd be willing to lend a hand, if there's anything I can do to help.

Contributor

kevindente commented Jan 31, 2014

@geekytime I added a proxy feature to my own fork already if you want to use it as short term thing until the plugin architecture is done. https://github.com/kevindente/testem/tree/apiproxy

I opened #362 to try out a simple implementation of a plugin system. I got a basic forwarding proxy working this way for my app. I'll try to get the proxy module bundled up as an installable plugin in the next day or two, if this approach seems like it's going to work.

Thanks for the proxying fork, @kevindente, I was just starting to want that.

To describe my own use case, since I see there's some tension around whether there should be anything this complicated in testing, is that I'm mocking an API so that I can test a web app under real-ish conditions. I did the mocking so the test server would go faster, but it still needs to be able to handle various types of HTTP requests for me to test the front end all the way to the interface.

I was actually really happy with Ember-cli's mocking hooks, they just check the package.json for a couple keys:

{
  proxyURL: "http://localhost:4021",
  proxyPath: "/api"
}

That's enough to tell the app to redirect requests coming in through /api paths over to :4021, and actually meets my use case satisfactorily enough that I could just have my mock server running and this would work fine.

Express middlewares etc might be nice for other cases, but for me, I'd rather use the same mock server as I'm using for front-end development anyway, so I'd almost prefer allowing me to provide my own responses to the proxied URL.

The very top of what I'd want would be a hook in the testem.json for starting a script, like a mock server. This would make it even easier to keep this coordination in the configuration, curious if that would meet others' needs.

Hey @kevindente, I'd really appreciate it if you could add some docs to your api proxy branch describing how to use it.

Contributor

stefanpenner commented Jul 29, 2014

@airportyh a good number of people are now maintaining a fork of this to suite there testing needs and goals. I strongly recommend you reconsider.

Collaborator

airportyh commented Jul 30, 2014

@kevindente @ghedamat could you write up some usage docs for your fork? What does the configuration look like?

airportyh reopened this Jul 30, 2014

Contributor

stefanpenner commented Jul 30, 2014

@airportyh thanks man for reconsidering :)

Collaborator

airportyh commented Jul 30, 2014

Contributor

ghedamat commented Jul 30, 2014

@airportyh I'm following up on #391 , tests seems to have crashed before they started, maybe you can re-trigger the build

we can keep the discussion here if you prefer

Contributor

ghedamat commented Jul 30, 2014

also, thanks! :)

Collaborator

airportyh commented Jul 30, 2014

@ghedamat thanks.

So a configuration example @ghedamat posted at airportyh#391 is

{
  "framework": "qunit",
  "test_page": "tests/index.html",
  "launch_in_dev": ["PhantomJS", "Chrome"],
  "proxies": {
    "/api": {
      "port": 4200,
      "host": "localhost"
    }
  }
}

The way I read this, /api and everything under it will be mapped to http://localhost:4200/. So, /api/search, will go to http://localhost:4200/search. Is that correct?

Contributor

ghedamat commented Jul 30, 2014

@airportyh nope, it will still got to http://localhost:4200/api/search

we could add another option to strip a prefix if you think it's needed

@kevindente implementation relies on https://github.com/nodejitsu/node-http-proxy and that api simply reroutes the entire request to the new host

this fits perfectly my use case but I can see how other might want a different behaviour

Collaborator

airportyh commented Jul 30, 2014

Can others in this thread chime in whether or not this is needed to meet
your needs?

On Wednesday, July 30, 2014, Mattia Gheda notifications@github.com wrote:

@airportyh https://github.com/airportyh nope, it will still got to
http://localhost:4200/api/search

we could add another option to strip a prefix if you think it's needed


Reply to this email directly or view it on GitHub
airportyh#218 (comment).

That would meet my needs, I think it's a great feature.

Contributor

ghedamat commented Jul 30, 2014

@flyswatter so you'd rather remove the part that is being proxied and have an option to redirect
so the /api/search will go to http://localhost:4200/search ? (just trying to be sure :p)

Oh on that question I think the proxy should strip off the proxy prefix. In Toby's example the search should go localhost:4200/search, not to :4200/api/search.

If you add on /api, you're making assumptions about the proxied-to server, and would now be requiring someone to strip out that prefix if the proxied server didn't use it.

If the proxied-to server needs an additional prefix, that should be provided in the options hash, ex:

{
  "framework": "qunit",
  "test_page": "tests/index.html",
  "launch_in_dev": ["PhantomJS", "Chrome"],
  "proxies": {
    "/api": {
      "port": 4200,
      "host": "localhost",
      "prefix": "/my-api-prefix",
      "suffix":".json"
    }
  }
}

In this example I added a suffix too, just to demonstrate how simple this kind of configuration could be.

Contributor

kevindente commented Jul 30, 2014

When I originally wrote this code, it was to cover the scenario of a single page app javascript file calling back to the server in a test. Given that scenario (which I'm guessing would be very common), I'd say the current proxy config stuff makes the most sense. The client calls back to API endpoints on the source server (Testem in this case), and for those specific endpoints testem needs to forward the request to another service (since it isn't actually hosting the endpoint itself). Seems like you'd want the URL to be transparently proxied in that case, without rewriting it.

On second thought, I am already handling the proxying I'm talking about with nginx, I guess it doesn't need to live in testem, I'm fine if the simple functionality is the default or the only one available.

Contributor

ghedamat commented Jul 30, 2014

yup I'm with @kevindente and prefer the current option (transparent proxy), but we can add more later if we think it's needed

Collaborator

airportyh commented Aug 1, 2014

Merged @ghedamat's solution.

airportyh closed this Aug 1, 2014

Contributor

stefanpenner commented Aug 1, 2014

👍

@stefanpenner Does ember-cli run the mock-server during testing? Is there a simple way to set it up to run the mock server during ember test so it works nicely with this feature? @kumavis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment