I use cucumber for lots of things. I really like it as a BDD environment.
So I'd like to use it as an external tool to test an API. I'd like to do things like:
Scenario: Hit api /info path and get info back
When I visit the API path '/info'
Then I should see the following text "Here's info on the API"
or something similar. I mainly want to treat the API as a black box and test only inputs and outputs. I don't plan on inspecting anything inside the API.
Most of the libraries I've looked at that work with Cucumber (for example Capybara) seem to be designed around Rack-based applications. I'd like something similar to that but with no dependency on Rack.
What gems, if any, exist that have no rack dependencies. Or is there a way to use Capybara to test an API that's on a remote server?
I wouldn't use Capybara to test a remote API because Capybara is made for testing applications is used for testing applications with a HTML UI (as Aslak points out in the comments).
Instead, I would use Cucumber* in conjunction with something like HTTParty which would be the tool used to make the HTTP requests and parse them neatly. Here's an idea:
When /^I visit the API path '(.*?)'/ do |path|
#result = HTTParty.get("http://theapi.com/#{path}")
end
Then /^I should see the following result:$/ do |result|
#result.should == result
end
The final step here you would use like this:
Then I should see the following result:
"""
{ success: true }
"""
* I would actually use RSpec personally, I find the syntax less clumsy.
I've been using cucumber against a Drupal application for some time now. It's working out well.
This helped me set up capybara with selenium
https://github.com/thuss/standalone-cucumber
If you want to use mechanize, it's a bit buggy. I had to use 0.3.0-rc3 as there were some issues following redirects etc. There are still a few issues with submitting forms with field names containing "[]" characters. I can't quite remember as another person on my team discovered that bug.
Related
I have gone through fitnesse user guide. But it seems difficult for me to follow since I want to test a web-service.
The problem is as below
I have a request xml file and response xml file.
In request file I have userid and logon id with values .
In response xml file I have location with value.
I need to test that whether I get expected location value , using fitness.
How can I do the test with fitnesse.
Out of the box FitNesse does not test anything. It is really a framework for collaboratively editing and executing tests. To test any sort of software you need to use fixtures. Often people write their own, but you can also use fixtures written by other people.
In the case of testing web services, you can possibly use RestFixture. It is designed to test REST based Web Services. Back when I had to test a TES interface, I chose to write my own using HttpClient and custom parser due to the way our other test fixtures worked.
I don't know anything about it, but you can also look at XmlHttpTest.
Ultimately, you with have to find a fixture that works for you, or build one. This is pretty much true of FitNesse, Cucumber, and most of the similar style tools.
I am writing a script that automates the completion a web form in my Rails app using the form entries given on the client side. However, this site uses Javascript, and so Mechanize is out of the question.
However, everything I've read about Mechanize's alternatives -- Watir Webdriver, Selenium, Capybara Webkit -- all focus seemingly exclusively on testing. However, my Rails web app would take in form entries from users, and then enter them using one of these tools into another website. For example, I would need to upload an image (ie :image) and enter in different text (ie :city) into form fields as part of this app, which would take the entries and enter them into the website.
So my first question: Can I use any Mechanize alternatives for something besides testing? And second: Can anyone refer to code examples on the web for non-testing usages of any of the above automators?
I don't have any concrete examples of javascript-enabled alternatives used in non-testing contexts, but I do have a suggestion: if you know the website that you will be submitting the form info to, it's probably better to find out what the javascript is doing and mimic that instead. Dig into the site's javascript code and figure out what type of data is being submitted to what URL, and just mimic that using standard HTTP operations -- skip the javascript rendering/interaction part altogether.
There is a lot of overhead incurred when rendering a page with javascript, which is why these tools (Watir, Selenium, Capybara and the like) are not generally used in actual client-facing application contexts.
Watir has a headless gem. You can give it a try watir headless
You should be able to use watir-webdriver to take the data (image, city) from one site and upload to other site. Below is brief code sample to help you get started.
require 'watir-webdriver'
$browser1 = Watir::Browser.new : chrome #You can use phantomjs for headless http://phantomjs.org/
$browser1.goto http://website1.com
city_field = $browser1.text_field (:id => 'city')
city = city_field.value
$browser2 = Watir::Browser.new : chrome
$browser2.goto http://website2.com
city_field_site2 = $browser2.text_field (:id => 'city')
city_field_site2.set city
I have a Rails 2.3.5 app which is serving a card game. I've been a bit lax in writing tests for it (read: I haven't written any :embarrassed:), and I'd like to make a start now.
From reading other questions, I think I probably want to be using Shoulda extending Test::Unit for unit testing.
I wondered about using Capybara extending RSpec for functional testing, but the majority of users' interaction with the app is via POST, which I understand Capybara doesn't handle.
Since this is a card game, I obviously need the ability to control rand; I also definitely need the framework to handle Javascript.
Is Test::Unit + Shoulda suitable?
Am I correct that Capybara can't handle POST? Can I work around that?
Is there a better option instead of Capybara?
Can these methods handle the randomness involved in a card-game? Presumably, for Test::Unit at least, I can just call srand at some early stage to fix the generator, but I don't know if that's doable for Capybara/RSpec/anything else.
Can anyone point me to resources dealing specifically with setting up Shoulda, Capybara and RSpec for Rails 2.3.5? It's a little hard to tell what's Rails 3 specific and what isn't.
Would I gain anything from adding Watir / Firewatir into the mix?
I realise the above questions are manifold, but they basically boil down to "does this work, or have you any better suggestions?"
If the majority of the users' interactions are via POST, is it via an API (as opposed to filling out forms or something)?
Just about any combination of RSpec/Shoulda/Capybara/Test Unit/Rack::Test could work for you depending on your need. They're all capable. However, these are my recommendations:
If you've decided you want integration testing via HTML pages, use Cucumber and Capybara
If you've decided you want integration testing via HTTP API, use RSpec and Rack::Test
You probably want to fake out randomness.
You probably don't need Watir/Firewatir.
It does look like you can make POST requests via some Capybara drivers:
http://suffix.be/blog/capybara-post-requests
When Rails moved to 3.0, RSpec went to 2.0 so for at least RSpec, you'd want RSpec and RSpec Rails 1.3.2.
By "fake out randomess", I mean redefine srand in your tests so you can predictably run them.
module Kernel
def rand
YourApp.rand
end
end
module MyApp
class << self
attr_accessor :rand
end
end
Then, before you have the user press the button, run a step definition like "When random returns 6", which will set MyApp.rand = 6.
I'm getting started with cucumber, and I have written the following step definition, which basically I copied from the rspec test I already had.
Given /^There is a picture on the screen$/ do
describe PagesController do
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
end
end
end
Now I'm also quite new to Rails. But this seems a bit long to me, can't I make it any shorter?
What you're doing there is a big antipattern when writing tests with Cucumber. You haven't broken down your step far enough—when you look at the test you've got, you're actually going through at least a couple of different steps, one of which isn't something you want to test. A better test for this would be:
Given I am on the home page
Then I should see a picture
The first step you get for free when you install capybara's web steps, provided you are using the default path helper in features/support/paths.rb. The second one would look like this:
Then "I should see a picture" do
page.should have_selector("img.picture")
end
That step is going to look for an image with a 'picture' class on it—my arbitrary definition of what a picture is in the context of your application.
Notice that I'm not checking the response status here. The idea behind cucumber (even moreso than Rspec) is that you test things from the perspective of the client. Arguably your client may be a client API, so perhaps checking the status code is appropriate, but in general with a web app, you're much more concerned about the UI, and a failing status code will manifest itself in other ways, such as a broken UI. Details like status codes are generally implementation details that shouldn't be tested from a BDD point of view (though they should be covered in your unit tests.)
FWIW, I also disagree with the assertion that the length of the test is what should determine whether you should be using Rspec or Cucumber. See my blog post on the matter: http://collectiveidea.com/blog/archives/2011/04/15/language-matters/
It would strongly recommend not using Cucumber until you're more familiar with Rails/Ruby. Cucumber adds a level of abstraction that can make things very confusing, frustrating and time consuming. Just get very good with RSpec first. Then when you want to do integration tests on your Rails app, use Capybara with RSpec. When you're comfortable using those gems, you can go to Cucumber.
Cucumber is about writing user stories. You then translate those Cucumber steps into lines of RSpec and Capybara.
If you are looking for brevity, I would recommend sticking to RSpec. Cucumber's main advantage is its readability to people who do not write code, while RSpec sacrifices that in order to be shorter. I tried to use Lettuce, a python analogue to Cucumber, on one of my projects and found it to be way too much work to keep up.
So, in short: if you want to write shorter tests, use RSpec. If you want your developer to edit your tests or you are working in a team, use Cucumber.
As a learning experience I'm developing a small Rails application that is supposed to query an existing SOAP API/web service (using the handsoap gem) and will simply present the information gathered there to a user.
I like using rspec and am getting used to cucumber for testing my applications. The part that has me stumped is how to test the interaction with the API, i.e. the 'non-presentation' part of passing back and forth XML requests and responses.
Any tips and pointers are very much appreciated!
Thanks!
Take a look at fakeweb gem.
It helps to stub network interoperability,
i.e. you can create test responses:
FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!")
and disable ability to send http requests:
FakeWeb.allow_net_connect = false
Net::HTTP.get(URI.parse("http://example.com/"))
=> raises FakeWeb::NetConnectNotAllowedError
I'm assuming you're talking about functional/integration style tests and not unit tests in which case I would probably consider mocking the interface for the web service and unit testing the code on a lower level.
But to return to cucumber. As Aslak Hellesøy points out in Stack overflow q 810410 there is nothing that should prevent you from doing this. When you have written the scenarios for what behaviour you are actually going to test you just have to instantiate the right objects in the step definitions and call the appropriate methods. Possibly also combining it with a few asserts on return values or content if that is what you need. See Rspec expectations for how to load rspec's should() with cucumber.
With the newest version of Handsoap, you can use a mock http-driver, to mock out at the http-level. See: Http::HttpMock and the example in tests/account_test.rb