0

I want to write a test using Rspec and Capybara.

I have a Post model and I want to add a draft attribute to it. If the user checks that field the post is saved as draft (draft = true). Only posts that have he attribute draft = false will show in the post index page. Posts with draft = true will only show in the page of the user who created that post.

I've never made a Rspec + Capybara test in my life. So I was wondering if someone could tell me how to start or give me an example. Thanks in advance!

schema.rb:

 create_table "posts", :force => true do |t|
    t.string   "title"
    t.string   "content"
    t.integer  "user_id"
    t.datetime "created_at",                               :null => false
    t.datetime "updated_at",                               :null => false
    t.integer  "comments_count",        :default => 0,     :null => false
    t.datetime "published_at"
    t.boolean  "draft",                 :default => false
  end

(By the way, do I need to post the model, controller or view pages?)

alexchenco
  • 53,565
  • 76
  • 241
  • 413

2 Answers2

2

To add on to new2ruby's answer you can also use the Feature/Scenario aliases provided by capybara in your integration tests.

I find it reads nicely:

require 'spec_helper'

feature 'Visitor views posts' do
    scenario 'shows completed posts' do 
        post = FactoryGirl.create(post)
        visit posts_path

        page.should have_content(post.title)
    end

    scenario 'does not show drafts' do
        draft = FactoryGirl.create(draft)
        visit posts_path

        page.should_not have_content(draft.title)
    end
end

I recently wrote a "getting started" blog post on using RSpec with Capybara for integration tests. Let me know if you have any questions on getting your codebase set up.

harlow
  • 844
  • 9
  • 17
  • 1
    Good to know. Didn't realize you had to call it out if its your own content. Will make sure I do so in the future. – harlow Oct 24 '12 at 18:26
  • @harlow Thanks! (Hey, I'm confused. I thought 'feature' was Cucumber stuff). – alexchenco Oct 25 '12 at 02:07
  • @alexchenco `feature/scenario` have been added to Capybara to alias `describe/it`. This brings the Gherkin style of integration to RSpec users and feels more natural for the people who historically used Cuc's. – harlow Oct 25 '12 at 12:14
  • @harlow so it means that Capybara is replacing Cucumber? – alexchenco Oct 25 '12 at 12:19
  • @alexchenco No not at all. Cucumber is still alive and well. However, internally our teams have started choosing RSpec + Capybara over Cucumber. – harlow Oct 25 '12 at 15:21
1

I've been following a basic pattern of model tests and integration tests. I've also been using FactoryGirl along with rspec and capybara. So... first off here is what my factory might look like:

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "person#{n}@example.com" }
    password "foobar"
    password_confirmation "foobar"
  end

  factory :post do
    sequence(:title) { |n| "Test Title #{n}"}
    string "Test content."
    published_at Time.now()
    comments_count 0
    draft false
    association :user

    factory (:draft) do
      draft true
    end
  end
end

Then I would make a model spec file (spec/models/post_spec.rb):

require 'spec_helper'

describe Post do
  let(:post) { FactoryGirl.create(:post) }

  subject { post }

  it { should respond_to(:title) }
  it { should respond_to(:content) }
  it { should respond_to(:user_id) }
  it { should respond_to(:user) }
  it { should respond_to(:published_at) }
  it { should respond_to(:draft) }
  it { should respond_to(:comments_count) }

  its(:draft) { should == false }
  its(:comments_count) { should == false }

  it { should be_valid }
end

Then I would make an integration test (spec/requests/posts_spec.rb):

require 'spec_helper'

describe "Posts pages" do

  subject { page }

  describe "index page when draft == false" do
    let(:post)  { FactoryGirl.create(:post) }

    before { visit posts_path }

    it { should have_content(post.title) }
  end

  describe "index page when draft == true" do
    let(:draft) { FactoryGirl.create(:draft) }

    before { visit posts_path }

    it { should_not have_content(draft.title) }
  end
end

You might try working through the rails tutorial at http://ruby.railstutorial.org/ It uses rspec, capybara and FactoryGirl for the tests.

Kevin K
  • 2,191
  • 2
  • 28
  • 41