0
votes

I'm really new on testing with rspec and capybara. I'm using devise for authentication on my app and I'll have to use an action to sign in in mostly all of my tests. I currently have a sign in test like this:

before do
        @john = User.create!(name: "John", email: "[email protected]", password: "password")
end

scenario "with valid credentials" do

        visit "/"

        fill_in "Email", with: @john.email
        fill_in "Password", with: @john.password
        click_button "Log in"

        expect(page).to have_content("Signed in successfully")
        expect(page).to have_content("Welcome, #{@john.name}")
        expect(page).not_to have_link("Sign up")
        expect(page).to have_link("Sign out")

end

How could I reuse that piece of code, so when I test another actions that requires the user should be signed in, I do all that before with a dryer code. Thanks in advance!

1

1 Answers

1
votes

You can use Warden test helpers along with FactoryBot to clean up your tests significantly. Since you already have Devise installed all you need to do to include Warden test helpers is to add this to your spec/rails_helper.rb

include Warden::Test::Helpers
Warden.test_mode!

This will allow you to simply call something like...

before do
  @john = FactoryBot.create(:user)
  login_as(@john, :scope => :user)
end

and then to logout simply...

logout(@john)

Setting up the user factory (which is where :user comes from in FactoryBot.create(:user) is simple to setup and reusable throughout your tests. Once you install the factory_bot_rails gem you can create a directory named factories and a file named users.rb...(spec/factories/users.rb) and add something like this with your specific User attributes...

FactoryBot.define do
  factory :user do
    first_name "John"
    last_name  "Doe"
    email "[email protected]"
    password "helloworld"
    password_confirmation "helloworld"
  end
end 

You can set up multiple users and other factories...but there are tons of examples out there so I won't get into all of that.

Note: I would keep the test in your question as is if the purpose is to test the user flow of filling out the form and logging in. But, for all other tests, the approach I layed out should serve you well and be a lot cleaner.