Is there an alternative to "it" in RSpec tests? - ruby-on-rails

Some RSpec methods have aliases for how you phrase them e.g. describe and context both do the same thing.
It's not always useful to start a spec statement with it - are there any alternatives to how one can phrase that part of the test?
e.g. it might be nice to phrase the following:
context "when copying a Page object" do
expect_that "the image gets copies" do
...
end
end
Are there aliases for it that one can use?

specify is a minimally documented synonym for it. example is also a synonym, but I'm not aware of any documentation.
There's also its, which has been factored out to a separate gem as of RSpec 3.0.

Related

Why is RuboCop replacing the word "should" with the word "does"?

I'm not sure what is causing it, but the word "should" is being replaced in my code with the word "does". I'm writing a spec in ruby on rails, and I'm trying to follow a BDD approach to my unit tests. One of their recommendations is writing each unit test as a whole sentence, starting with the word, "should", so I wrote the following test:
it 'should not return if there are no existing activities on the project' do
end
The code is being replaced by the following:
it 'does not return if there are no existing activities on the project' do
end
Notice that the word "should" has been replaced. Is this RuboCop? If so, what is the rule I disable to prevent this from happening?
If it's not RuboCop, what could it be?
Well it is actually something Rubocop does for you through RSpec/ExampleWording. Rubocop has an Rspec Style guide, you can check the part about "Should" in Example Docstrings
From the docs:
Do not write 'should' or 'should not' in the beginning of your example
docstrings. The descriptions represent actual functionality, not what
might be happening. Use the third person in the present tense.
So disabling it is actually a bad practice and you should stick to the docs and write your docstrings accordingly.
You can disable RSpec/ExampleWording

before(:all) except one - is it possible?

I use before(:all) in my tests for database initialization, which causes no problems for my test cases... except one. I'd like to run this special case before or after others, as I want to initialize database for it separately. Is there some way to do this? I'd like to avoid replacing before(:all) with before(:each), because I'd like to keep my tests fast. Is it possible?
before(:all) except one - is it possible?
Probally not. before(:all) runs before all the examples in that scope and there is no way to hoist examples above it.
I think a better idea is to work around the problem and just create different contexts:
RSpec.describe Thing do
context "with :all" do
before(:all) do
# ...
end
# ...
end
context "without :all" do
# ...
end
end
Use shared contexts or the outer scope if you need to share setup steps or variables. Use shared examples if you want to run the same examples in different contexts.
I'd like to run this special case before or after others, as I want to
initialize database for it separately. Is there some way to do this?
You can use the --order defined option when running rspec to run the tests sequentially. However this sets you up for test ordering issues than can mask critical bugs in the application. Fast test are worthless if they don't catch bugs.
You can also use :order => :defined metadata to set the order per context. And for the reason in the beginning of this question this is a fools errand.

What does expect() do in rspec/cucumber?

In Michael Hartl's Rails Tutorial, many examples use an expect() method. Here's one such example in a cucumber step definition:
Then /^she should see her profile page$/ do
expect(page).to have_title(#user.name)
end
This same example can be written as such to the same effect:
Then /^she should see her profile page$/ do
page.should have_title(#user.name)
end
Why use expect()? What value does it add?
There's a documentation on the rspec-expectations gem about this.
Why switch over from should to expect Basically:
should and should_not work by being added to every object. However, RSpec does not own every object and cannot ensure they work consistently on every object. In particular, they can lead to surprising failures when used with BasicObject-subclassed proxy objects.
expect avoids these problems altogether by not needing to be available on all objects.
A more detailed reasons for this is placed in: RSpec's New Expectation Syntax
expect is a bit more universal. You're passing an object or a block to rspec's expect method, rather than attempting to call a should method on objects that are outside of your control. As a result, expect is coming more and more into favor among developers.

rSpec vs Shoulda confusion

I started reading a book about rSpec as my basic intro to testing my Rails app. I started writing tests like:
it 'is valid with a name' do
coaster = FactoryGirl.build(:coaster)
expect(coaster).to be_valid
end
But then someone pointed me at Shoulda and can now write tests like:
it { should validate_presence_of(:name) }
Note: I realise the two tests posted are not the same, merely just examples of each type.
What I need some clarification of is, is Shoulda an alternative to rSpec or is Shoulda an addon to it?
Which way would others go about this? The Shoulda tests seem simpler and shorter overall.
Basically any thoughts and comments would be helpful.
Shoulda just adds additional matchers to RSpec.
http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames
The BDD style is exposed through expect, expect is more natural language assertions. First of all, notice that the expect require is just a reference to the expect value, whereas with the should require, the value is being executed. The should style extends each object with a should property which is called monkey patch in ruby. Here is a good article which explains and compares this two assertion mechanism.

Should I write rails tests with the def or test keyword?

This seems like a simple question but I can't find the answer anywhere. I've noticed that in general, tests in a Ruby on Rails app can be written as:
test "the truth" do
assert true
end
or
def the_truth
assert true
end
It seems newer material writes tests the first way, but I can't seem to find a reason for this. Is one favored over the other? Is one more correct? Thanks.
There has been a shift in recent years from short, abbreviated test names to longer, sentence-like test names. This is partly due to the popularity of RSpec and the concept that tests are specs and should be descriptive.
If you prefer descriptive test names, I highly recommend going with the test method. I find it to be more readable.
test "should not be able to login with invalid password" do
#...
end
def_should_not_be_able_to_login_with_invalid_password
#...
end
Also, because the description is a string it can contain any characters. With def you are limited in which characters you can use.
I believe the first method was implemented starting with Rails 2.2.
As far as I am aware, it simply improves readability of your code (as def can be any function while test is used only in test cases).
Good luck!
As Mike Trpcic suggests you should check out RSpec and Cucumber. I'd like to add that you should also take a look at:
Shoulda (http://github.com/thoughtbot/shoulda/tree/master)
Factory Girl (http://github.com/thoughtbot/factory_girl/tree/master)
Shoulda is a macro framework for writing concise unit tests for your models/controllers, while the second is a replacement for fixtures.
I would suggest doing your testing with either RSpec or Cucumber. I use both to test all my applications. RSpec is used to test the models and controllers, and Cucumber tests the Views (via the included Webrat functionality).

Resources