从我读过的关于Rails 5.1新系统规范的所有内容中,我的理解是Rails现在在内部处理数据库事务.
来自Rspec的博客:"[之前]您的测试和您的测试代码无法共享数据库事务,因此您无法使用RSpec的内置机制来回滚数据库更改,而是需要像数据库更清洁的gem.使用系统测试,Rails团队已经做了艰苦的工作以确保不是这种情况,因此您可以安全地使用RSpec的机制,而无需额外的宝石."
我的经历不同:
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是否在内部处理数据库事务,还是仍需要数据库清理程序?有没有人遇到这个,或者可以指向我相关信息?
我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
我的前端是一个基于EmberJS的应用程序.它本质上是完全异步的,所以用Capybara测试它是痛苦和痛苦.另一方面,Ember提供了一个开箱即用的优秀测试套件,使验收测试变得有趣和有效.
通常情况下,使用固定装置或后端模拟验收Ember应用程序.但是对模拟的测试并不能让我满意:
所以我想测试真正的后端!设置Ember以使用本地后端实例进行测试是微不足道的.但问题是后端将在各个测试甚至测试会话之间保持其状态.
这就是为什么我想在Rails中实现一个特殊的公共API:
我是一个对Rails有粗略了解的前端开发人员.Factory Girl和Database 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
我正在使用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
我有一个旧的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) 如果我单独使用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) 在使用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事务策略不同?
我已经database-cleaner为我的 rails 4 应用程序进行了配置,每次运行测试时,我发现我的数据库在test和development环境中都被清除了。
我的配置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) 我目前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 以获得干净的数据库状态。
我有一个使用 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 运行中的种子在本地重现错误,并且在调试时遇到了真正的麻烦。
database-cleaner ×10
rspec ×6
ruby ×3
capybara ×2
rspec-rails ×2
cucumber ×1
factory-bot ×1
postgresql ×1
selenium ×1