Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails rspec测试比rails控制台慢得多_Ruby On Rails_Ruby_Rspec_Factory Bot - Fatal编程技术网

Ruby on rails rspec测试比rails控制台慢得多

Ruby on rails rspec测试比rails控制台慢得多,ruby-on-rails,ruby,rspec,factory-bot,Ruby On Rails,Ruby,Rspec,Factory Bot,我花了一整天的时间试图弄明白为什么我的rspec rails测试套件需要很长时间才能完成(并非总是这样),我使用--profile来确定哪些测试需要很长时间,而且似乎每个测试访问数据库都需要30秒的时间 以下面的示例行为例: MyModel.create(args) 如果我在rails控制台中运行这一行,它会立即完成,但是如果我将它包括在rspec测试中,它会使该测试的完成时间增加30秒。另外,这一行只是一个例子,如果我在执行rails c时使用Factory girl或使用创建关系,请注意,

我花了一整天的时间试图弄明白为什么我的rspec rails测试套件需要很长时间才能完成(并非总是这样),我使用--profile来确定哪些测试需要很长时间,而且似乎每个测试访问数据库都需要30秒的时间

以下面的示例行为例:

MyModel.create(args)

如果我在rails控制台中运行这一行,它会立即完成,但是如果我将它包括在rspec测试中,它会使该测试的完成时间增加30秒。另外,这一行只是一个例子,如果我在执行
rails c
时使用Factory girl或使用创建关系,请注意,加载需要一些时间,因为它正在启动数据库并加载将“立即”可用的rails类


每个测试规范每次都会重新创建一个干净的DB slate,因此它应该比在控制台中运行相同的命令花费更多的时间(因为DB已经设置好了)。您可以通过在(:all)之前正确地使用
,并设置测试,以尽可能多地使用同一实例,而无需重新记录,从而减轻此问题。

但要延长30秒吗?我能做些什么来减少这里的开销吗?30秒似乎太多了,但这完全取决于你的测试是如何构造的(例如,它们可能会多次清除数据库)。我为我的一个简单模型添加了一个测试文件,结构告诉你什么?30秒是一次性税还是每个规格30秒?您的种子或数据库设置挂钩中是否有需要花费很长时间的内容?每次db调用需要30秒。因此,如果我在同一个规范中创建了4个模型实例,那么运行该特定规范将需要2分钟。在下一个规范中清洗并重复(我将用注释编辑上述规范)FactoryGirl工厂是否默认定义了所有不动产?可能是后面有很多疑问。您是否尝试从Rails控制台运行FactoryGirl.create(:course)?别忘了
rails c-s
.p.s。我也遇到了FactoryGirl工厂运行缓慢的问题,这是由许多工厂(也称为图片工厂)造成的,这些工厂每次都上传并裁剪一张图片(占用了大部分时间)。我在控制台(rails c-s)中运行FactoryGirl.create(:course)和FactoryGirl.create(:course\u assignment)他们两人都在不到一秒钟的时间内跑掉了。如果我在我的规范中使用相同的行,它们每个都需要30秒以上。
require 'simplecov'
require 'metric_fu/metrics/rcov/simplecov_formatter'
SimpleCov.formatter = SimpleCov::Formatter::MetricFu
SimpleCov.start 'rails'

# 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 'database_cleaner'
require 'carrierwave'

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

ActiveRecord::Migration.maintain_test_schema!

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.order = "random"
  config.mock_with :rspec
  config.include JsonSpec::Helpers
  config.include FactoryGirl::Syntax::Methods
  config.include Devise::TestHelpers, type: :controller

  # config.raise_errors_for_deprecations!
  config.infer_spec_type_from_file_location!

  config.expect_with :rspec do |c|
    c.syntax = [:should, :expect]
  end

  config.before(:suite) do
    begin
      EphemeralResponse.activate
      DatabaseCleaner.strategy = :truncation
      DatabaseCleaner.clean_with(:truncation)
      DatabaseCleaner.start
      # FactoryGirl.lint
    ensure
      DatabaseCleaner.clean
    end
  end

  config.before(:each) do
    Bullet.start_request if Bullet.enable?
  end

  config.after(:each) do
    if Bullet.enable? #&& Bullet.notification?
      # Bullet.perform_out_of_channel_notifications
      # Bullet.end_request
    end
    DatabaseCleaner.clean
  end

  config.after(:suite) do
    EphemeralResponse.deactivate
  end
end
require 'spec_helper'
describe CourseAssignment do

    let(:instructor) { create(:instructor) }
    let(:student) { create(:student, id: 2) }
    let(:bundle) { create(:bundle) }
    let(:course) { create(:course) }
    let(:assignment) { create(:course_assignment, course: course) }

    it { should belong_to(:course) }
    it { should belong_to(:user) }

    describe 'CourseAssignment deletion' do
        it 'should not delete the Course or the Student' do
      instructor.courses << course # 30 seconds
      instructor.courses.last.students << student # 30 seconds
      CourseAssignment.create(course_id: course.id, user_id: student.id) # 30 seconds
      expect{CourseAssignment.last.destroy}.to change(CourseAssignment, :count).by(-1)
      expect(Student.count).to eq(1)
      expect(Course.count).to eq(1)
      expect(instructor.courses).to include(course)
        end
    end

    describe 'Student deletion' do
        it 'should delete the CourseAssignment & Student, but not the  Course' do
      instructor.courses << course # 30 seconds
      instructor.courses.last.students << student # 30 seconds
      CourseAssignment.create(course_id: course.id, user_id: student.id) # 30 seconds
      expect(student.course_assignments.count).to eq(2)

      expect{student.destroy}.to change(CourseAssignment, :count).by(-2)
      expect(Course.last.students).to be_empty
      expect(Course.count).to eq(1)
      expect(instructor.courses).to include(course)
        end
    end

    describe 'Course deletion' do
        it 'should delete the CourseAssignment' do
      instructor.courses << course # 30 seconds
      instructor.courses.last.students << student # 30 seconds
      CourseAssignment.create(course_id: course.id, user_id: student.id)

      expect{course.destroy}.to change(Course, :count).by(-1)
      expect(CourseAssignment.count).to be(0)
      instructor.reload
      expect(instructor.courses).to be_empty
        end
    end

    it 'should require a course_id' do
        no_course_id_assignment = CourseAssignment.create(course_id: '', user_id: 2) # 30 seconds
        no_course_id_assignment.should_not be_valid
    end

    it 'should require a user_id' do
        no_student_id_assignment = CourseAssignment.create(course_id: 2, user_id: '') # 30 seconds
        no_student_id_assignment.should_not be_valid
    end

end
# MySQL.  Versions 4.1 and 5.0 are recommended.
#
# Install the MySQL driver:
#   gem install mysql2
#
# And be sure to use new-style password hashing:
#   http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
  adapter: mysql2
  encoding: utf8
  database: xxxx
  username: xxxx
  password: xxxx
  host: localhost

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  adapter: mysql2
  encoding: utf8
  database: xxxx_test
  username: xxxx
  password: xxxx
  host: localhost

production:
  adapter: mysql2
  encoding: utf8
  host: localhost
  database: xxxx
  username: xxxx
  password: xxxx
  port: 3306