I am developing a system composed of two different rails applications (server and client) which communicate via rest web services.
I have tests for each app individually, but I would like to add some test for the integration between the two platforms, to assert that one creates a request compatible with what the other is expecting.
Any hints would be appreciated.
I have a similar architecture and we are using VCR in order to record all server side responses and avoid make requests always. It could turn annoying and right now I'm looking for a way to clean data from server after every request
I think VCR could be a good start point in order to test integration between your apps.
You can find documentation here -> Relish Docs
I think there could be several approaches here, depending what you have implemented..
If the client Rails app has user interface, try to write Selenium tests to perform the integration test in your local dev environment or a staging environment that has both deployed. (not ideal if the interface is still a prototype, changing frequently...)
Maybe part of the client can be written as a Ruby gem (e.g. the communication rest api is a ruby gem). When the server app in testing environment, the server Rails app can use the Client gem to run integration test, i.e. call the module function, the same function is used by client. The client Rails app can also use the gem to make requests to the server. Here's a good guide to start migrating some of your reusable code to rubygem.
Related
The application is using Minitest on Rails 4 with Capybara.
I'd like to write an integration or feature test that stubs a websocket connection (the application uses Faye as a client) to return a specific message (like I'm used to doing with Webmock).
Is this possible? If so, can you provide an example? My research has not turned up any examples.
Your research hasn't shown up any examples because it's not really what you're supposed to be doing in feature tests. Feature tests are supposed to be end-to-end black box tests where you configure the data as required for the app to generate the desired results and then all interaction is done via the browser (no mocking/stubbing which technically alter your apps code). Additionally when connections between the browser and a 3rd party service are involved there is nowhere in your app where you can mock it.
It may be possible to stub a websocket connection from the browser with a programmable proxy like puffing-billy, however it's generally cleaner to produce a small fake version of the 3rd party service for testing purposes (sinatra app, etc) and point the browser at that rather than the original service when you need to craft custom responses. Additionally, there are a lot of fakes already out there, depending on what service you are using (fake-stripe, fake-s3, etc), which may provide the functionality you're looking for.
We have a Rails app that acts HTTP API only. On the client side, Ember.js is currently used. We are not overly impressed by Ember and really like the approach Meteor.js takes. So we'd like to exchange the client side with Meteor.js and communicate with the Rails server via websockets that speak the Data Distribution Protocol (DDP), so we can keep using the models, mailers and controllers in Rails. Implementing server side of DDP should be easy.
However, we're unsure how to make Rails talk websockets. We found Reel, which seems to make it easy to accept websocket requests in a standalone environment. Reel seems great as we'd like to implement the DDP on top of the Celluloid stack anyway. But what about running Reel in the Rails environment? Would we need "rails runner" for that? And we'd like to keep using the existing controllers to dispatch incoming requests (like, to add/change/remove resources). Is that even possible without having the request coming through Rack?
Any input is appreciated.
It's a bit late, but I've implemented DDP in Ruby, you can check it out here:
https://github.com/d-snp/ruby-ddp-server
It includes an implementation of EJSON as well. It's built on top of celluloid-websocket, and can be ran simply as a rack app.
I've made an integration with RethinkDB that can be used as a reference to build your own collections implementation.
https://github.com/d-snp/ruby-ddp-server-rethinkdb
I've also made a sample chat application that can be found here:
https://github.com/d-snp/celluloid-rethinkdb-chat
It's something that I have been longing to do as well, to integrate old "legacy" Rails code. Here is the best way I have found:
Since you would not be using any of Rails router/controller/views, but just the ability to read data and push it to the client, I recommend you use Rails to create JSON apis to the database, and deploy the code, then in Meteor you can consume the data via the http package, this would happen on the server at a regular interval and populate the MongoDB with the normalized data you need, then it would serve the browser client.
I am working on such an application that will keep a normalized version of the data in Mongo, and a relational version of the data in mySql (through Rails) this way I can preserve the legacy Rails functionality that I dont want to rewrite in JS, and get the benefit of Meteor for the one page that I need it most.
We have a Rails App and a Sinatra API with separate codebases. They need to work together with the same database.
We can create a record using the API, and then display a page for that record using the Rails app. When creating the record using the API, there are many other records that need to be created at the same time. This all happens fine on the Rails app.
Here's the problem: What is the best way to test that when the API creates the record, all the other records are created and the page renders properly on the Rails app?
I am writing a test in the Rails app for this. Since the API is separate from the Rails app, I can create a mock. But the mock needs to do everything the API would do, so it is not really a mock.
Is it possible (or practical) to include in the Rails app the API file that contains the call to create the record?
Or is there a better way to test for this?
Well, you have two web applications. That is, two applications that expose a (more or less) public interface on the Net and that respond to HTTP calls.
Why do not use a HTTP client to invoke all of the two servers and perform a complete test (a "workflow test", if you like)?
You can probably use any existing web testing tool for this, or write a test script with any language.
No, it is not possible to include in the Rails app a file from the API.
They are hosted on different servers. Even if I got it working on my local machine, it would not work in production.
EDIT: Actually, this is not true. If the file only needs to be shared for testing, then it will only run on the local machine (unless there is some kind of CI system). So the production environment doesn't matter. Only the testing (CI) environments matter.
I am building a REST Web Service layer on top of a Rails app that will be used by an Iphone application. The response format is XML.
I would like to build some acceptance tests that should be external to the rails stack (and should test everything, including the http server). The test scenarios are quite complex, involving the process of searching/posting/reviewing an order. What would be the best solution to accomplish this?
a. Ruby script using curl/curb to fetch the request and Hpricot to parse the request
b. Selenium
c. ..
It would also be nice that those tests could be used as integration tests (therefore, run on every git commit). What integration solution would you recommend?
a. Integrity
b. CruiseControl
c. something else
I've used three approaches over this last few years
Active-resource
I found this to be too concerned with looking like active-record to be a great solution. In some cases I had to patch parts of it to work as I'd like a REST client to behave.
Rest-client
This gem is very good - well documented and does works as expected. I combined this with my own simple DSL and it's worked out better than a generic testing framework
XML over HTTP
I use this for performance testing. Very flexible but the learning curve is higher than Rest-client. If you go down this approach you could use the Net::HTTP core class or the HTTParty gem (I haven't tried this but it looks great>
A really good resource is this Net::HTTP cheat-sheet
For ad-hoc testing I've also found the Rest Client add-in for Firefox very useful.
Use selenium-rc in ruby mode and you'll be a happy camper. Webrat/Cucumber already do this for you so you can just put that in a second project and run the tests that way, all you'll have to do is override the host (so instead of localhost you'll be using your domain).
As to CI I'm afraid I don't know the best one.
you can't possibly mean mks integrity...if so, the answer is anything but. CC is a good CI tool. really good.
I use a web service to convert files. The service returns the converted file as an HTTP POST, along with identifier data. My app receives the response, updates its database and saves the file to the appropriate location.
At least that's the idea, but how do I develop and test this on a local machine? Since it isn't publicly facing, I can't provide a directive URL. What's the best way to handle this? I want to keep the process as clean as possible, and the only ideas I can come up with have seemed excessively kludgey.
Given how common REST API development is, I assume there are well-established best practices for this. Any help appreciated.
The solution will change a bit depending on which server your using.
But the generally accepted method is using the loopback address: 127.0.0.1 in place of a fully qualified domain name. Your server may need to be reconfigured to listen on this IP address, but that's usually a trivial fix.
example: http://127.0.0.1/path/to/resource.html
You can use curl or even your browser if your application has a proper frontend. There are many other similar tools to test this from a command line, and each language has a set of libraries for establishing http connections and transferring data along them.
If your machine isn't accessible to the service you are using, then your only option would really be to build a local implementation of the service that will exercise your API. A rake task that sends the POST with the file and the info would be a nice thing so you could start your rails app locally, and then kick off the task with some params to run your application through its paces.
This is the case any time you are trying to develop a system that can't connect to a required resource during development. You need to build a development harness of sorts so that you can exercise all the different types of actions the external service will call on your application.
This certainly won't be easy or straight forward, especially if your interface to this external service is complicated. Be sure to have your test cases send bad POSTs to your application so that you are sure you handle both what you expect, and what you don't.
Also make sure that you do some integration testing with the actual service before you "go-live" with the application. Hopefully you can deploy to an external server that the web service will be able to access in order to test. Amazon's EC2 hosting environment would let you set up a server very quickly, run your tests, and then shut down without much cost at all.
You have 2 options:
Set up dynamic dns and expose your app to the outside world. This only works if you have full control over your network.
Use something like webrat to fake the posts to your app. Since it's only 1 request, this seems pretty trivial.
Considering that you should be writing automated tests for this, I'd go with #2. I used to do #1 when developing facebook apps since there was far to many requests to mock them all out with webrat.
If your question is about testing, why don't you use mocks to fake the server? It's more elegant than using Webrat, and easier to deploy (you only have one app instead of an app and a test environment).
More info about mocks http://blog.floehopper.org/presentations/lrug-mock-objects-2007-07-09/
You've got some info about mocks with Rspec here http://rspec.info/documentation/mocks/