标签: database-cleaner

是否还需要使用Rails系统规范的DatabaseCleaner?

从我读过的关于Rails 5.1新系统规范的所有内容中,我的理解是Rails现在在内部处理数据库事务.

来自Rspec的博客:"[之前]您的测试和您的测试代码无法共享数据库事务,因此您无法使用RSpec的内置机制来回滚数据库更改,而是需要像数据库更清洁的gem.使用系统测试,Rails团队已经做了艰苦的工作以确保不是这种情况,因此您可以安全地使用RSpec的机制,而无需额外的宝石."

我的经历不同:

  1. 升级到Rails 5.1后,我的Rspec功能测试全部通过.
  2. 我将'功能'规格重命名为'系统'规格.所有测试都通过了
  3. 我删除了Database Cleaner gem,并删除了所有引用rails_helper.rb.JS测试现在由于validates uniqueness错误而失败.非JS测试通过.

我的测试非常简单.

let(:subject) { page }
let(:user) { create :user, name: "TestUser" }
it "displays the user page", :js do
  visit user_path(user)
  it is_expected.to have_content "TestUser"
end
Run Code Online (Sandbox Code Playgroud)

数据库清理器禁用,:js => true我得到user named TestUser already exists.随着:js => false测试通过.

系统测试和rspec的当前情况如何?Rails是否在内部处理数据库事务,还是仍需要数据库清理程序?有没有人遇到这个,或者可以指向我相关信息?

rspec ruby-on-rails database-cleaner ruby-on-rails-5

25
推荐指数
1
解决办法
4939
查看次数

DatabaseCleaner + RSpec:正确的配置是什么?

database_cleaner在我的rails应用程序中包含了gem.遵循git repo上给出的示例,并包含以下代码spec_helper :

方法1

  config.before(:suite) do
   DatabaseCleaner.strategy = :transaction
   DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
   DatabaseCleaner.cleaning do
    example.run
   end
  end
Run Code Online (Sandbox Code Playgroud)

当我运行rspeci get错误时NoMethodError:undefined method 'cleaning' for DatabaseCleaner:Module.

所以我做了一些研究,发现我可以用以下内容替换config.around上面的块:

方法2

config.before(:each) do
 DatabaseCleaner.start
end

config.after(:each) do
 DatabaseCleaner.clean
end 
Run Code Online (Sandbox Code Playgroud)

要么

方法3

config.around(:each) do |example|
  DatabaseCleaner.start
  example.run
  DatabaseCleaner.clean
end
Run Code Online (Sandbox Code Playgroud)

方法2和方法3都运行良好.
我还查看了database_cleaner的git repo,发现该cleaning方法实际存在,并使用以下代码:

def cleaning(&block)
     start
     yield
     clean
   end
Run Code Online (Sandbox Code Playgroud)

这与我在例子3中所做的完全相同.如果确实存在那么为什么它不可访问?我在这里错过了一些东西.还有更多设置?或者方法2或3更好?

rspec ruby-on-rails rspec-rails ruby-on-rails-4 database-cleaner

21
推荐指数
1
解决办法
6638
查看次数

在前端运行集成/验收测试.需要一个前端API来告诉Rails为每个测试设置哪个数据库状态

我的前端是一个基于EmberJS的应用程序.它本质上是完全异步的,所以用Capybara测试它是痛苦痛苦.另一方面,Ember提供了一个开箱即用的优秀测试套件,使验收测试变得有趣和有效.

通常情况下,使用固定装置或后端模拟验收Ember应用程序.但是对模拟的测试并不能让我满意:

  • 它不会揭示后端和前端之间可能的API不一致,竞争条件等.
  • 以这种方式测试后端业务逻辑是不可能的.这些测试不是集成测试.
  • 最后,验收测试需要持久性,因此您必须在模拟中复制后端行为.这非常繁琐,你有效地最终实现了两个后端.

所以我想测试真正的后端!设置Ember以使用本地后端实例进行测试是微不足道的.但问题是后端将在各个测试甚至测试会话之间保持其状态.

这就是为什么我想在Rails中实现一个特殊的公共API:

  • 只有在使用特定标志或env var运行Rails时,API才可用.
  • Rails以非测试模式运行,提供正常的API调用,就像在生产中一样.
  • 在每次测试之前,前端调用特殊API,告诉Rails这个特定测试需要哪个数据库设置.
  • 当收到对特殊API的调用时,Rails会清理数据库并使用请求的数据填充它.例如,要从购物车中测试项目删除,数据库应该在购物车中有三个项目.
  • Rails完成API请求,前端开始测试.
  • 前端运行测试步骤,使用正常的后端API,就像在生产中一样:登录,创建帖子,评论它们.它还会尝试做一些禁止的事情,例如在未登录时编辑帖子,超出文本长度限制等,并验证后端是否拒绝禁止的操作.
  • 当前端运行下一个测试时,它将再次调用特殊API.对于此特定测试,Rails将丢弃先前测试产生的状态并设置新测试状态.

我是一个对Rails有粗略了解的前端开发人员.Factory GirlDatabase Cleaner似乎是适合这项工作的工具,但绝对没有关于如何在Rails正常测试环境之外使用它们的信息.我想我需要一个控制器或一个Rails引擎.

所以问题是:如何在Rails中创建一个API,前端可以使用它来告诉Rails使用fixture工厂设置某个数据库状态,而Rails则以非测试模式运行,即提供REST API和没有通过RSpec/Capybara/Cucumber运行?

额外功能:应在前端定义夹具工厂属性,以便将测试代码存储在一个位置.因此,后端应该能够通过特殊API接受夹具工厂属性.默认值仍然可以在后端的代码库中定义.

我相信这可能成为验收/集成测试的最佳实践.如果我设法实现它,我保证发布一个gem.

integration-testing ruby-on-rails acceptance-testing database-cleaner factory-bot

14
推荐指数
1
解决办法
756
查看次数

Capybara webkit的数据库清理问题

我正在使用Cucumber编写我的集成测试和数据库清理程序以保持我的数据库清理.一切都很完美,因为我的测试不需要Javascript.

我可以使用Capybara webkit使这些最后的测试通过,但是我的数据库根本没有被清理.

这是我的features/support/env.rb文件:

require 'simplecov'
SimpleCov.start 'rails'
require 'cucumber/rails'

Capybara.default_selector = :css
Capybara.javascript_driver = :webkit

begin
  require 'database_cleaner'
  require 'database_cleaner/cucumber'
  DatabaseCleaner[:active_record].strategy = :transaction
rescue NameError
  raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end


Before do
  DatabaseCleaner.start
end

After do |scenario|
  DatabaseCleaner.clean
end
Run Code Online (Sandbox Code Playgroud)

我想类似的东西这个检查是哪个驱动程序所使用的水豚,但没有奏效.我也试过了这篇文章第三部分中提到的hack,但后来没有任何工作......

我真的不知道如何实现这一点,任何帮助将不胜感激.

提前致谢.

ruby-on-rails cucumber capybara capybara-webkit database-cleaner

10
推荐指数
1
解决办法
5051
查看次数

将capybara从1.0.1升级到1.1.4会使database_cleaner破坏我的规格

我有一个旧的Rails应用程序升级到版本3.2.11,它有很多使用capybara版本1.0.1编写并使用selenium驱动程序运行的请求规范.使用database_cleaner使用截断策略在每次测试后清理数据库.

我想使用poltergeist而不是selenium并将capybara从1.0.1升级到1.1.4以便能够使用最新版本的poltergeist.只更改capybara gem(及其依赖项)引入了运行我的规范的问题.

在每个规范之后,我一直在清理处理程序中从Postgresql数据库中获得死锁错误.我的spec_helper很基本,看起来像这样:

RSpec.configure do |config|
  config.mock_with :rspec

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
Run Code Online (Sandbox Code Playgroud)

我得到的错误是这样的:

An error occurred in an after hook
  ActiveRecord::StatementInvalid: PG::Error: ERROR:  deadlock detected
DETAIL:  Process 41747 waits for AccessExclusiveLock on relation 17612 of database 16396; blocked by process 41752.
Process 41752 waits for RowExclusiveLock on relation 17529 of database 16396; blocked by process 41747.
HINT:  See server log for query details.
: …
Run Code Online (Sandbox Code Playgroud)

selenium rspec ruby-on-rails capybara database-cleaner

8
推荐指数
2
解决办法
1380
查看次数

数据库清理程序无法在最小的轨道中工作

如果我单独使用rake minitest:controllers它,我的Minitest控制器测试工作正常,但是当我运行时,rake minitest:all我得到验证失败错误.这是因为电子邮件已经用于模型测试.我使用DatabaseCleaner清理数据库但无法清理数据库.

我的数据库清理代码:

require "database_cleaner"
DatabaseCleaner.strategy = :transaction

class MiniTest::Rails::ActionController::TestCase
    include Devise::TestHelpers

    def setup
      DatabaseCleaner.start
    end

    def teardown
      DatabaseCleaner.clean
    end
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails-3.2 database-cleaner

7
推荐指数
2
解决办法
4788
查看次数

自定义事务不适用于rspec中的database_cleaner

在使用MySql的Rails 4.0应用程序中,我们将rspec与使用strategy:transaction配置的database_cleaner gem一起使用,以清理每个测试用例的数据库.如果我们有自定义事务,应该回滚,它不起作用.

没有database_cleaner gem并且只使用标准方式:

config.use_transactional_fixtures = true
Run Code Online (Sandbox Code Playgroud)

一切都如预期的那样.但是对于使用JavaScript运行功能测试,我们需要database_cleaner将夹具删除策略更改为:截断.

我们如何将database_cleaner与自定义事务一起使用?为什么它与标准的rspec事务策略不同?

rspec ruby-on-rails ruby-on-rails-4 database-cleaner

7
推荐指数
1
解决办法
1751
查看次数

database_cleaner 正在擦除我的开发数据库

我已经database-cleaner为我的 rails 4 应用程序进行了配置,每次运行测试时,我发现我的数据库在testdevelopment环境中都被清除了。

我的配置rails_helper如下:

ENV["RAILS_ENV"] ||= 'test'
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'database_cleaner'
Rails.env = "test"
# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec …
Run Code Online (Sandbox Code Playgroud)

rspec ruby-on-rails-4 database-cleaner

6
推荐指数
1
解决办法
2350
查看次数

DatabaseCleaner.clean_with(:truncate) 不会重置自动递增的 id

我目前DatabaseCleaner在运行 PostgreSQL 的 Rails 项目中使用,并将其设置如下。

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation, { pre_count: true, reset_ids: true })
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
Run Code Online (Sandbox Code Playgroud)

在我的一个 rails 测试套件中,我打印了一个实例的 id。我认为它应该是相对较小的数字,因为 clean_with(:truncate) 假设清除数据库并对其运行真空。但每次我运行测试时它都会增加。

测试通过,它使用什么序列并不重要。但为什么clean_with(:truncation)不以它应该的方式工作?

====== 编辑 ======

这在 RSpec 测试的范围内。我知道序列编号对性能没有影响,但对每个 :suite 进行昂贵的清理 (:truncation) 并使用廉价且快速的清理 (:transaction) 会。所以我想了解为什么clean_with(:truncation)在运行测试套件之前不为我重置 id 以获得干净的数据库状态。

ruby postgresql ruby-on-rails rspec-rails database-cleaner

6
推荐指数
1
解决办法
3681
查看次数

DatabaseCleaner 引发 NoMethodError:未定义的方法 `rollback' 为 nil:NilClass

我有一个使用 rspec 并包含 DatabseCleaner 的 rails 应用程序,以确保每次测试之间的测试数据库都是干净的。

DatabaseCleaner 在我们的配置中spec/rails_helper.rb使用

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
Run Code Online (Sandbox Code Playgroud)

我们一直在 ci 环境中看到间歇性错误,其中单个测试将失败

 1) LibraryHours Required fields Library Hour must have a location
 Failure/Error:
   DatabaseCleaner.cleaning do
     example.run
   end

 NoMethodError:
   undefined method `rollback' for nil:NilClass
 # ./spec/rails_helper.rb:66:in `block (2 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

我们无法使用 rspec 运行中的种子在本地重现错误,并且在调试时遇到了真正的麻烦。

ruby rspec ruby-on-rails database-cleaner

6
推荐指数
1
解决办法
1042
查看次数