How would you test multi user interaction with Cucumber/webrat?
Meaning that there must be more than one user logged in. Good example would be simple chat application, where I want to send message from one user to another and check if the other user received the message.
I'd like to test at integration level, without any stubbing or mocking.
I'd use Selenium RC with two separate instances controlling separate browsers. I imagine there may be other tools out there for web-based integration tests that are as useful as Selenium or even more, but, personally, I have never met one yet.
I know how this should be done, I just cannot find the right place to do it:
You need to create a second Webrat::Session instance the original webrat_session that you get for free can be one party, while the new one can be the other. I might make two new named sessions just so I could name them.
alice = Webrat::Session.new #I think I have to hook this into merb and I don't know how
bob = Webrat::Session.new
alice.visit url(:chat)
bob.visit url(:chat)
alice.fill_in('chat', 'Hi, bob')
bob.visit url(:chat) #simulate poling
bob.responce.body should_contain "alice: Hi, bob"
HTTP is a pull protocol, this means that users can't be notified when another performs an action. Because of this it is sufficient to simply switch users half way through your scenario. To take your chat example, here's the cucumber scenario that you would use
Scenario: Send a message
When I login in as "user_a"
And I go to the chat page
And I fill in "message" with "blah blah"
And I press "Send"
And I switch_user_to "user_b"
And I go to the chat page
Then I should see "blah blah"
Even if your page is sending polling requests via ajax to get the latest messages it is still sending a request. In that case you could test the ajax call by simply doing a step where user_b calls the url that the ajax request is calling.
Related
I am using Ruby on Rails 3.2.2, cucumber-rails-1.3.0, rspec-rails-2.8.1, capybara-1.1.2 and factory_girl-2.6.3. I have a Scenario that tests the user sign up like the following:
Scenario: I register an user
When I fill in "Name" with "Foo"
And I fill in "Email" with "foo_bar#email.com"
And I fill in "Password" with "test_password"
And I click button "Register"
Then I should be redirected to the homepage
and I am trying to state a new Feature (within a separated file) where to implement a Scenario that, by using a token, should test the signed up user confirmation process to be properly completed (note: in reality, this process involves an email message delivering but I do not want to test if that email was sent; just ignore it for this question). Since I would like to test exclusively the confirmation process, I thought to implement a new Feature/Scenario where to state something like Given I am a registered user for which to run the Scenario: I register an user.
Scenario: I confirm an user
Given I am a registered user # Here I would like to run the 'Scenario: I register an user'
When I go to the confirmation page
And I enter the confirmation token
Then ...
In few words, I thought to call an entire Scenario within another Scenario.
Even if I can use the FactoryGirl gem to "create"-"register" an user, I prefer to proceed with the above approach because I'd tests ("practically" speaking, those "represent" "invisible people" that, managed by the Selenium gem, open my browser and perform actions) to behave as much as possible like "real people" behave, and so those test steps to implicitly follow all "real" steps that should be made in reality in order to sign up a new user. By following this approach I can test whether or not the application "interiors" are properly working.
Is it a correct approach? If no, how could/should I proceed?
One of the principles of well designed tests is that you exercise a particular feature in all of its various forms, but beyond that presume it to be working within the context of other tests that are exercising other features. That is, once you've tested that users can register, you should not be re-testing the same thing unless you're testing it in a different way.
The phrasing "Given I am a registered user" is something that implies the user has already successfully registered. You shouldn't go testing registration at this point since that's outside the scope of the test you're trying to perform.
Each test should have a mandate and it should stick to it. If you don't limit yourself your tests will spiral into a uselessly inter-dependent mess where changing one thing requires changing every other thing hooked in to it.
The syntax to run a scenario within a step is:
Given /^I authenticate successfully$/ do
Given 'I am on the login page'
And 'I fill in "Email" with "eddie#hotmail.com"'
And 'I fill in "Password" with "secret"'
When 'I press "Login"'
Then 'I should see "Welcome"'
end
Final thoughts: In general, have your Feature file not have any "fill in" --- just have it describe the actions, and have your steps do the dirty work.
I am implementing some smoke tests to our website.
I'm using a Given/When/Then format for existing automated acceptance tests/User stories. But now I want to do an initial smoke test of:
Given I'm on the homepage
Then I should see "Welcome To The Site"
Am I missing something? Is it "ok" to not have a When?
Tools Used: MVC3, SpecFlow, Nunit, Watin
It is completely valid syntax to omit any of Given, When or Then (and even to mix them in any order - specflow doesn't care.)
However, for the purpose of readability, rather than omit the When I often rephrase the Given, i.e.
When I view the homepage
Then I should see "Welcome To The Site"
I prefer to omit the Given section, because the When is supposed to indicate what the tested action is.
If the code for the step binding is the same and you want to re-use it, you can always bind your given and my when to the same method.
[Given(#"I'm on the homepage"]
[When(#"I view the homepage"]
public void NavigateToHomePage()
{
...
I think you are really missing the point here. You ALWAYS need a When. That is the thing you should be testing! What you can leave out are the Givens
What you should be saying is;
When I visit the homepage
Then I should see "Welcome To The Site"
Given When Then is really a nicer way of representing a state machine.
Given some initial state // in your case, non
When I perform some action // in your case, visiting the homepage
Then I have some final state // in your case, text displayed to a user
What I like to do is to think about all the things that must be present to allow the When to happen. In your case there doesn't seem to be any initial state. But consider if you had some web application. You would need to have an initial state before visiting the homepage (you'd need to make sure the user is logged in);
Given a user // user must be stored in the database
And the user is logged in // a logged in user must be in the session
When the user visits their homepage
Then the user should see "Welcome To Your Homepage"
An alternative scenario would be;
Given no logged in user // some people would leave this Given out, but I add it for completness
When a user visits their homepage
Then the user should be redirect to the login page
As someone correctly pointed out, most BDD tools don't actually differentiate between Given When Then but you should! The verbose nature of 'Given When Then' has been chosen as its easier for us humans to understand and helps our thought processes. A machine couldn't care less what you call the steps. With this being the case, you should make every effort to utilise the keywords correctly at all times.
Additional
BDD structure is no different to a well set-out test with arrange, act, assert.
The benefit of BDD though is that it gives a verbose structure to tests. This helps devs have domain appropriate conversations with product owners - Behaviour Driven Development.
If you aren't having these conversations, there's very little value in using BDD over normal tests practices.
I tend to see Given as the equivalent of traditional pre-conditions. When as the equivalent of the test action. And Then as the equivalent of the expected result.
Therefore, if there are no pre-conditions, I would leave out Given and simply focus on When and Then:
When I'm on the homepage
Then I should see "Welcome To The Site"
Specflow will allow you to use Given or When, but Visual Studio will also allow you to write a single class that is 1000's of lines long. Just because both are possible, does not mean either is 'right'.
Apologies for the thread resurrection...
I'd have probably gone with:
Given there is a homepage
When I view the homepage
Then I should see "Welcome To The Site"
I like to keep at least one Given, When and Then in each Scenario - don't forget you can also use And and But (not that they're particularly relevant to this scenario). You can even just make a bullet-point style list with *.
I would say:
Given I have requested the home page
When the home page loads
Then I should see 'Welcome To The Site'
You don't need a When. I like the think of the Given/When/Then keywords like
Given - This is a preparation step, do anything you need to be able to perform the test
When - This should be an action that your test will verify.
Then - This should be where you verify your test based on the action performed in the When steps.
As previously suggestion they only affect the execution order.
I am doing acceptance testing with Steak on a Ruby on Rails application. Imagine I want to test the functionality of a form.
It should create an user if all the fields are correct.
It should not create a user if any of the fields are incorrect.
In the first case, a message will inform that the user has been created: 'The user has been created'
In the second case error messages will indicate the errors.
I can base my tests on the information displayed. That is, the first test pass if the correct message is displayed.
Or I can base my tests on the changes on the database. That is, the first test pass if the database has a new user which contains the data entered.
Or I can assert for both conditions, database should change and the appropriate message should be displayed.
What is the conceptually adequate way of testing this kind of behaviour, according to Behaviour Driven Development?
What is the practical way of testing this kind of behaviour, according to being a Pragmatic Programmer?
Generally, keep to what the user sees.
However, sometimes there's more than one user of the information. Perhaps, once the data has reached the database, another application then uses that data (fairly typical for internal projects!)
If you can't automate with both applications together, then asserting the contents of the database, or perhaps verifying resources on a RESTful URL, can be a good way to go.
If you do this, it will probably change the nature of your scenarios. Rather than saying, Then the database should contain XYZ, try something like:
Given that Fred Brown lives at 25 Warrington Grove, Springfield
When Fred orders a deckchair
Then the warehouse should receive an order:
Deckchair
Quantity: 1
To: Fred Brown
25 Warrington Grove
Springfield
So you're always looking at the capabilities of the system, rather than just the data - even if the warehouse doesn't really receive it in your scenario, you're showing why the data has to be in that particular place and form.
This way, you also leave yourself the option of using a real UI, or a RESTful URL, etc. later - the step is independent of the implementation you choose.
My BDD practices involve using Cucumber. I try my hardest to keep it to what the user sees. That is, any When and Then statements should reflect user input or user visuals.
In your case I would make sure that a success message appears afterwards, and then I would (if possible) look for data on the screen indicating the application is aware of the object. For instance, if you added a comment to a blog post you should fill in the post, hit the 'accept' button, see a 'Message Posted' success message, and then also see your content on the page as a new post.
You should back up your user-driven BDD tests with unit and sometimes controller tests to make sure everything behind-the-scenes is functioning correctly as well.
I tend to use RSpec and verify that things get added to the database, methods are returning expected results etc. But I also use Cucumber to make sure the user sees what the user is expecting to see (But I don't really let cucumber care about what's in the DB).
I hope this helps. If you aren't using cucumber yet I highly recommend it for BDD testing in conjunction with RSpec. You should check out the book (comes in electronic PDF form) - I started with that and it helped a ton with my testing practices:
http://www.pragprog.com/titles/achbd/the-rspec-book
I would agree with keeping with what the user see's, up to a point.
If there is some kind of layer that could potentially persist a value in memory, such that it might show up on the site as if it was in the db, when it's not actually been written out TO the db.. then it might be a good idea to back up your 'what the user's see's' with some checks at the db level.
I need to develop an application which should help me in getting all the status,messages from different servers like Twitter,facebook etc in my application and also when i post a message it should gets updated in all the services. I am using authlogic for authentication. Can anyone suggest me what gems/plug-ins i can use..
I need API help to get all the tweets/messages to be displayed in my application and also ways to post the messages to the corresponding services by posting it from my application. Can anyone help me from design point.
Walk through what you'd want to do in your head. Imagine the working site, imagine your webapp working before you start. So your user logs in (handled by authlogic) and sees a textbox called "What are you doing right now?". The user fills in a status message and clicks "post". The status message appears at the top of their previously posted messages.
Start with the easy part. Create a class that posts to two services. Use the twitter gem and rfacebook to post to two already defined services. In the future, you'll want to let the user associate services to their account and you would iterate through the associated services and post the message to each. Once you have this working, you can refactor or polish the UI a bit to round out this feature. I personally would do the "add a social media account to my profile" feature towards the end.
Harder is the reading of the data (strangely enough) because you're going to have to figure out how to store it. You could store nothing but I suspect you'd run into API limits just searching all the time (could design around this). I would keep a little cache of posts associated to the user's social media account. In this way, the data model would look like this:
A user has many social media accounts.
A social media account has many posts. (cache)
Of course, now you need to schedule the caching of the posts. This could be done manually, based on an event (like when they login) or time based. So when the update happens, you load up the posts for that social media account and the user will see the posts the next time they hit the page. For real-time push to the client's browser while they stare at the screen, use faye (non-trivial) and ajax to pull the new posts to the top of the social media stream view.
The time based one is tricky because you'd either have to have a cron job run or have rails handle it all with a gem like clockwork. But then you have to leave rails running. I've also solved this by having a class in /lib do all the work and a simple web call kicks off the update. But it wasn't in a multi-user use case. So that might not work. In any case, you'll want to have some nice reusable code for these problems since update requests can come from many different sources.
You'll also have to deal with the API limits. When pulling down content from twitter, you won't get everything. That will just have to be known by the user or you'll have to indicate a "break in time" somehow.
The UI should be pretty easy (functionally anyway), because you know which source the post/content is coming from. It'd be easy to throw a little icon next to the post to display which social media site it's coming from.
Anyway, good luck, sounds like a fun project.
I am trying to build a free web application using ruby/rails It should be able to send sms through online forms of various mobile operators. (like this one (in russian)).
So, I need to
wait for the user, who wants to send an sms through my website.
establish connection to operator website. Probably, using Mechanize.
retrieve captcha
show captcha to the user
allow user to enter a message and captcha
submit form on operators website (with message, captcha, phone number)
The connection to the operator website should be alive during all this process (otherwise captcha will change). As far as I understand, I need to create a (sub)process each time sms is sent.
Could you please advise what is the best way of handling this in rails\ruby?
I am still rather new to web-development...
Should I use threads? forks? popen? using PTY? some external gem? How should I communicate with my process?
Assuming there's nothing special about the operator's web site, no, you don't need to keep a connection alive during the whole process. Generally speaking, forms on web pages work like this: You visit the URL, your web browser downloads the page with the form on it. In your case, it will also have an <img> tag or similar to show the CAPTCHA. Once your browser has downloaded the page, the connection is severed. After you fill out the form and click on Submit, your web browser opens a new connection to the server and sends the data, and the server sends its response (whatever page is shown after you click Submit).
All your program has to do is emulate this experience. So: 1) Download the page with the form on it. Scrape the form fields (make sure you don't miss any hidden fields--with a CAPTCHA there will probably be some) and the CAPTCHA. 2) Build a page to show your user that includes the CAPTCHA and a form with all the fields they need to fill out. If there were hidden fields in the original form, make sure you include their values (as hidden fields in your form) as well, because when the user submits your form you'll need them. 3) Then, when the user submits your form, send the data, including the hidden values and what the user entered for the CAPTCHA, to the operator. 4) Finally, check if the operator indicated success, and build a page to tell your user.
If you're doing this in Rails, you'll probably have two methods in your controller: One called e.g. 'show' (steps 1 and 2 above) that will scrape the CAPTCHA and other info from the operator's site and show the user your form view, and one called e.g. 'send' (step 3 and 4 above) that the form will submit to, and which will take their data and send it to the operator's web site, collect the response and tell your user if it was successful or not.
Note: You'll want to read the operators' terms of service before you bother with any of this. I'm fairly certain that this kind of thing will be against their TOSes and if they notice your server sending a lot of requests their way they're going to block you pretty quick.
To answer another question of yours, you can use DRb or background_job (aka BJ) to actually accomplish the sending in the background so that after your user submits the captcha they don't have to wait for the response. Or you could wrap this in ajax and have the DRb/BJ process notify you when the sms sending has happened so you can notify the user of success or any problems.
Typically opening threads in Ruby is something to avoid as there are so many great gems that do what we need. Not to say that you shouldn't use threads, just that for the most part it's probably already been done really well.