Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the argument against using before, let and subject in RSpec tests? [closed]

I just started writing RSpec tests, and I came across thoughtbot's Style Guide, which recommends against let, let!, before and subject (among others).

I've also read similar suggestions in a few other places (including the old RSpec docs warning about before(:all)), but I can't seem to find the actual argument against them.

So the question is:

Why shouldn't I be using those methods in my tests? What is the better approach?

like image 682
Topher Fangio Avatar asked Oct 13 '12 01:10

Topher Fangio


People also ask

What does subject mean in RSpec?

Summary: RSpec's subject is a special variable that refers to the object being tested. Expectations can be set on it implicitly, which supports one-line examples. It is clear to the reader in some idiomatic cases, but is otherwise hard to understand and should be avoided.

What is let in RSpec?

let generates a method whose return value is memoized after the first call. This is known as lazy loading because the value is not loaded into memory until the method is called. Here is an example of how let is used within an RSpec test. let will generate a method called thing which returns a new instance of Thing .

Do not use should when describing your tests?

Don't use should Do not use should when describing your tests. Use the third person in the present tense. Even better start using the new expectation syntax. See the should_not gem for a way to enforce this in RSpec and the should_clean gem for a way to clean up existing RSpec examples that begin with 'should.

What RSpec method is used to create an example?

The it Keyword The word it is another RSpec keyword which is used to define an “Example”. An example is basically a test or a test case. Again, like describe and context, it accepts both class name and string arguments and should be used with a block argument, designated with do/end.


1 Answers

Interesting question; something that I want to know more about as well.... So dug in a bit, and here is what I uncovered:

Thoughtbot style guide dictum about let, etc.

  1. In an earlier version of the style guide, there's more to that statement:

    Avoid its, let, let!, specify, subject, and other DSLs. Prefer explicitness and consistency.

  2. ThoughtBot folks made a post on let name let's not. See also the link to the Github Commit Comment conversation

  3. On one of their recent podcasts Joe Ferris, the CTO of ThoughtBot, explains why it's not a good idea to use let and subject. Check out the podcast titled Something Else Was Smellier from the 27m37s mark onwards for the next 5 minutes.

  4. Testing Anti-pattern 'Mystery Guest' which is dealt with in detail in an older ThoughtBot blogpost is the main reason for why not to use let and its cousins.

To summarize my understanding of all the above very succinctly:

Using let et al makes it difficult to understand what's happening within the test on a quick glance, and requires the person to spend some time in making the connections.

Write tests such that it is easy to understand without much effort.

In addition, using let liberally in tests results in over-sharing among the tests, as well as makes implicit common fixtures - i.e. having a common fixture to start with for every test being written even when it does not apply.

before(:all)

The argument against using before(:all) is straight-forward. As explained in the old rspec documentation:

Warning: The use of before(:all) and after(:all) is generally discouraged because it introduces dependencies between the Examples. Still, it might prove useful for very expensive operations if you know what you are doing.

before(:all) gets executed only once at the start of the ExampleGroup. As such there is a potential to inadvertently introduce dependencies between the Examples. Thoughtbot's assertion about the tests not being easy to understand applies to this as well.

In conclusion, the advise for writing better specs seems to be:

  1. Write tests such that they are easy to understand on a quick glance.
  2. Know what you are doing.
like image 81
Prakash Murthy Avatar answered Oct 19 '22 03:10

Prakash Murthy