2
\$\begingroup\$

Here's a test from a Rails app I'm working on. I want to know if I'm using describe, let, before, expect, etc in the proper way.

It is an integration test using capybara and FactoryGirl:

require 'spec_helper'
describe "UserPages" do
 subject {page}
 describe "profile page" do
 let(:user) {FactoryGirl.create(:user)}
 before do
 sign_in user
 end
 it { should have_selector('h1', text: user.name)}
 it { should have_selector('title', text: user.name)}
 describe "follow unfollow buttons" do
 let(:other_user) {FactoryGirl.create(:user)}
 describe "following another user" do
 it "should increment the followed user count" do
 visit user_path(other_user)
 expect do
 click_button "Follow"
 end.to change(user.followed_users, :count).by(1)
 end
 it "should increment the other user's followers count" do
 expect do
 click_button "Follow"
 end.to change(other_user.followers, :count).by(1)
 end
 describe "toggling the button" do
 before {click_button "Follow"}
 it {should have_selector('input', value: 'Unfollow')}
 end
 end
 describe "unfollowing a user" do
 before do
 user.follow!(other_user)
 visit user_path(other_user)
 end
 it "should decrement the followed user count" do
 expect do
 click_button "Unfollow"
 end.to change(user.followed_users, :count).by(-1)
 end
 it "should decrement the other user's followers count" do
 expect do
 click_button "Unfollow"
 end.to change(other_user.followers, :count).by(-1)
 end
 describe "toggling the button" do
 before { click_button "Unfollow"}
 it{should have_selector('input', value: 'Follow')}
 end
 end
 end
 end
 describe "if logged in" do
 let(:user) {FactoryGirl.create(:user)}
 before do
 sign_in(user)
 end
 describe "it should have a tweet box" do
 describe "posting a message" do
 let(:user) {FactoryGirl.create(:user)}
 before {visit user_path(user.id)}
 subject {page}
 it {should have_selector("input", type: "text-field")}
 end
 end
 describe "on another users page" do
 let(:user) {FactoryGirl.create(:user)}
 let(:other_user) {FactoryGirl.create(:user)}
 before do
 sign_in user
 visit user_path(other_user)
 end
 subject{page}
 it "should follow user after clicking button and unfollow after that" do
 expect {click_button "Follow"}.to change(other_user.followers, :count).by(1)
 expect {click_button "Unfollow"}.to change(other_user.followers, :count).by(-1)
 expect {click_button "Follow"}.to change(user.followed_user, :count).by(1)
 expect {click_button "Unfollow"}.to change(user.followed_users, :count).by(-1)
 end
 end
 describe "home page" do
 before do
 sign_in user
 visit "/users"
 click_link "Home"
 end
 it {page.should have_content "Your Timeline"}
 end
 end
 describe "if not logged in" do
 describe "on another users page" do
 let(:user) {FactoryGirl.create(:user)}
 let(:other_user) {FactoryGirl.create(:user)}
 before do
 visit user_path(other_user)
 end
 subject{page}
 end
 end
 describe "FollowUnfollows" do
 describe "Post to /relationships" do
 let (:other_user) {FactoryGirl.create(:user)}
 let (:user) {FactoryGirl.create(:user)}
 before do
 sign_in user
 end
 it "click Follow button" do
 visit user_path(other_user)
 end
 end
 end
end
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 28, 2013 at 15:25
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
  1. Use contexts rather than describe on context.
  2. make sure to keep the same depth with same contexts (story -> login_state -> page -> user_action)
  3. dry your "let, subject, before"s

    subject { page }
    let (:other_user) { FactoryGirl.create(:user) }
    let (:user) { FactoryGirl.create(:user) }
    contexts "logged in" do
     before { sign_in user }
     describe "other user's profile page" do
     before {visit user_path(other_user.id)}
     ...
     end
     describe "profile page" do
     before {visit user_path(user.id)}
     ...
     end
     ...
    end
    contexts "logged out" do
     ...
    end
    ...
    
answered Jun 15, 2013 at 4:31
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.