noizZze

RSpec: Hierarchical Specifications

RSpec is full of great features, but some of them either not very well documented or hidden to a naked eye. No wonder if you never discovered hierarchical specifications.

Traditionally, we write specifications like this:

1
2
3
4
5
6
7
describe AClass, "when doing this" do
    ...
end

describe AClass, "when doing that" do
    ...
end

Now imagine that you have some very similar specs with some common initialization:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
describe AClass do
    before do
        ...
    end

    describe "when doing this" do
        before do
            ...
        end
        ...
    end

    describe "when doing that" do
        before do
            ...
        end
        ...
    end
end

You can see that you have common initializations for examples from both specifications and specific initializations for examples from each.

In the previous post I wrote that I prefer not to define helper methods outside the specification definition as they become global and tend to intersect with methods defined in other specs. So, what is the solution?

Assuming that you have a method “authenticate” that you need to call before every example in several specifications, you can define an upper-level specification “authenticated” and group other specs, like this:

1
2
3
4
5
6
7
8
9
10
11
12
describe AClass, "(authenticated)" do
    before do
        authenticate
    end

    describe "when doing this" do ... end
    describe "when doing that" do ... end

    def authenticate
        ...
    end
end

Now you have it all in a safe way!