Search code examples
ruby-on-rails-4rspeccapybarafactory-botdatabase-cleaner

Rspec does not save records to DB


I'm writing tests for my rails_4 applicatation. I use rspec, selenium, capybara, database_cleaner, site_prism and factory girl.

I use 2 databases in my app, and in me tests I need to check that records in 1st DB are equal records in 2nd DB...

But when I run my tests:

  • database_cleaner doesnt clean my database after every "it"
  • when I post form with selenium to save category, then I see this category in categories/index and categories/:id/show. But Category.count returns me 0 !!!

Please help me to correctly setup rspec environment:

My spec_helper.rb:



    # This file is copied to spec/ when you run 'rails generate rspec:install'
    ENV["RAILS_ENV"] ||= 'test'

    require File.expand_path("../../config/environment", __FILE__)
    require 'rspec/rails'
    require 'rspec/autorun'
    require 'capybara/rspec'
    require 'capybara/rails'
    require 'shoulda/matchers'
    require 'selenium-webdriver'
    require 'site_prism'
    require 'database_cleaner'

    # Requires supporting ruby files with custom matchers and macros, etc,
    # in spec/support/ and its subdirectories.
    Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

    # Checks for pending migrations before tests are run.
    # If you are not using ActiveRecord, you can remove this line.
    ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

    RSpec.configure do |config|

      config.fixture_path                               = "#{::Rails.root}/spec/fixtures"
      config.use_transactional_fixtures                 = true
      config.infer_base_class_for_anonymous_controllers = false

      config.include Capybara::DSL

      config.order      = "random"
      config.color      = true
      #config.tty        = false
      #config.formatter  = :progress 
    end

My support/capybara.rb:



    Capybara.register_driver( :selenium ) do |app| 
      Capybara::Selenium::Driver.new( app, :browser => :firefox )
    end

    Capybara.configure do |config|
      config.default_selector  = :css
      config.javascript_driver = :selenium
      config.default_driver    = :selenium 
      config.app_host          = 'http://0.0.0.0:3000'
      config.default_wait_time = 3
    end

My support/mobile_market_pages.rb:



    Dir[Rails.root.join("spec/pages/*_page.rb")].each{ |f| require f }

    module MobileMarketPages

      class Navigation
        include Capybara::DSL

        def login_page
          LoginPage.new
        end

        def categories_page
          CategoriesPage.new
        end
      end
    end

My support/hooks.rb:



    DatabaseCleaner.strategy = :truncation

    RSpec.configure do |config|

      config.before(:each) do
        DatabaseCleaner.start
        @page = MobileMarketPages::Navigation.new
        @page.login_page.load

        @page.login_page.has_email_input?
        @page.login_page.has_password_input?
        @page.login_page.has_login_button?

        User.create!(
          email:                 '[email protected]', 
          password:              'admin12345', 
          password_confirmation: 'admin12345'
        ) if User.count == 0

        @page.login_page.email_input.set    '[email protected]'
        @page.login_page.password_input.set 'admin12345'
        @page.login_page.login_button.click
      end

      config.after(:each) do
        DatabaseCleaner.clean
      end 

    end

Example of spec:



    it 'User create new root category without properties and chieldren' do
      @page.categories_page.load
      @page.categories_page.has_add_category_button?
      @page.categories_page.add_category_button.click

      category  = FactoryGirl.build(:category)

      @page.categories_page.new_category.title.set               category.title
      @page.categories_page.new_category.description.set         category.description      
      @page.categories_page.new_category.order.set               category.order
      @page.categories_page.new_category.icon.set                category.icon
      @page.categories_page.new_category.create_button.click  

      expect( Category.count          ).to eq(1)
      expect( Ios::Category.count     ).to eq(1)
      expect( Android::Category.count ).to eq(1)

      [id, title, description, order, icon].each do |param|
        postgres_param = Category.first.param
        ios_param      = Ios::Category.first.param
        android_param  = Android::Category.first.param

        expect( postgres_param ).to eq( ios_param     )
        expect( postgres_param ).to eq( android_param )
      end      
    end

Typical Error:



    1) Categories Page User can create new root category User create new root category without properties and chieldren
    Failure/Error: expect( Category.count ).to eq(1)

    expected: 1
    got: 0

    (compared using ==)
    # ./spec/functional/categories_spec.rb:61:in `block (3 levels) in '

My factories:



    FactoryGirl.define do 

        factory :value do
            value       { Faker::Lorem.word }
        end

        factory :media do
            type        { 'Image'                                                  }
            local_path  { 'http://www.acsu.buffalo.edu/~rslaine/imageNotFound.jpg' }
            order       { Faker::Number.number(4)                                  }
        end

        factory :product do
            title       { Faker::Lorem.words(2).join(' ') }
            description { Faker::Lorem.paragraph(3)       }
            order       { Faker::Number.number(4)         }

            medias []
            values []
        end

        factory :property do
            title       { Faker::Lorem.words(2).join('') }
        end

        factory :category do
            title       { Faker::Lorem.words(3).join(' ')                          }
            description { Faker::Lorem.paragraph(3)                                }
            order       { Faker::Number.number(4)                                  }
            icon        { 'http://www.acsu.buffalo.edu/~rslaine/imageNotFound.jpg' }

            properties []
            products   []
        end

    end

Help me please!


Solution

  • The problem was in comparing instance attributes of my model. I changed my spec file to this:

    
    
        it 'User create new root category without properties and chieldren' do
          @page.categories_page.load
          @page.categories_page.has_add_category_button?
          @page.categories_page.add_category_button.click
    
          category = FactoryGirl.build(:category)
    
          @page.categories_page.new_category.title.set           category.title
          @page.categories_page.new_category.description.set     category.description       
          @page.categories_page.new_category.order.set           category.order
          @page.categories_page.new_category.icon.set            'http://www.acsu.buffalo.edu/~rslaine/imageNotFound.jpg'
          @page.categories_page.new_category.create_button.click  
    
          expect( Category.first.id ).to eq( Ios::Category.first.id     )
          expect( Category.first.id ).to eq( Android::Category.first.id )
    
          %w(title description order icon).each do |param|
            postgres_param = Category.first.send(param)
            ios_param      = Ios::Category.first.send(param)
            android_param  = Android::Category.first.send(param)
    
            expect( postgres_param ).to eq( ios_param     )
            expect( postgres_param ).to eq( android_param )
          end      
        end
    
    

    Data was not written to DB, because transaction fails... as I understood.