What is the correct way to write query specifications in RSpec?

tl; dr: go to the last paragraph

I recently tried to use RSpec query specifications for more targeted testing.

Here is what my testing looks like:

  • the general specification of the characteristics of the cucumber , that is, the user goes to the post with a comment, upvotes to the comment and the author receives points
  • model specifications , if the model really has some functionality, i.e. User#upvote(comment)
  • controller specs where I block most things and just try to make sure the code goes as I expect
  • look through the specifications if there is something complicated in the view, for example, rendering the upvote link only when the user has not already started, and they will also be hatched

The problem is that I have a specific script that is causing the error, and everything seems to work at the model / view level, where I cannot reproduce it.

It makes me write an integration test, which I can also do in a cucumber. The problem arises when I can really reproduce it, and I need to find out why this is happening. Usually this means playing tests, changing things, and seeing what happens.

For example, create a comment that belongs to the user who is trying to boost, try to vote with an expired session, etc. However, it is really a huge pain to write in Cucumber, because of the need to write a script, and then specify each step.

At this point, I prefer to write a query specification because it is lower and allows me to do something directly. The problem is that I'm not quite sure how to write the specification of the request correctly or what rules.

A simple example:

 visit login_path fill_in "Username", :with => user.username fill_in "Password", :with => user.password click_button "Log in" 

against

 post sessions_path(:username => user.username, :password => user.password) 

or even something lower, for example

 session[:user_id] = user.id # this actually doesn't work, but the idea is there 

Both of these examples achieve the same, they will register the user. I know that the answer to which to choose is based on what I need to check, but this does not answer the correct, traditional way for this.

I tried to find something about query specifications, but they are not described anywhere. The RSpec book does not apply to them; the RSpec documentation does not say anything.

What is the correct way to write query specifications? When should you use capybara and when only the Rails' #get and #post instead of clicking buttons and visit transition paths?

+6
source share
2 answers

In relation to requests, I believe that the agreement should adhere to testing user behavior and interaction with the interface, which means loading a page, filling out a form, etc. A website user cannot establish a session or interact directly with variables specifying a request.

I was often tempted to skip page loads and form interactions by sending or setting variables in request specifications (for speeds, especially heavy ajax specifications), but it really violates the purpose of the request specification.

As mentioned in the comments, you should test the behavior of the controller / view in other types of specifications.

+3
source

First sermon ....

I think the natural progression of YOU that the writer is testing is:

  • controller
  • Model
  • Inquiries
  • combination of Request, Controller, and Model specifications.

I know that at first I began to look at the controller, because it was easier to understand.

Then you get into the model specification, for non-happy things way ...

Then you understand that rspec does not actually represent the view, so you start to see dumb errors in Airbrake, so you say shoot ... I need to check the looks and the workflow. Therefore, the specification of the request.

Finally, you get older and understand that all 3 are important and should be used sparingly, but accordingly. Now I’m only at step 4 ... too many query specifications, and you spend 5 minutes on the whole package on a medium-sized application. sucks.

To answer your question:

I am testing a workflow and views that I need to “see” (using page.should or any complex JS (like jquery ui selectors) with capybara in the request specification.

If I just need to make sure that the controller variables were created or do something quickly with a message for an invalid path, due to the workflow ... I use the controller. For example, POST for an IPN controller in paypal ...

You will be surprised how much this covers. This gives you the opportunity to test models for all the remote things that you need, for total cross cases.

Honestly, I would say that using Fixtures and Test Unit for integration tests ... they still like better, faster ... stronger ... etc.

0
source

Source: https://habr.com/ru/post/907163/


All Articles