如何测试依赖于 Rails 并使用 Rails 命令的 gem
How to test a gem that depends on Rails and uses Rails commands
我正在制作一个 gem 来执行 Rails 命令(例如 rails g model Item
)。当我在 Rails 项目中使用它时,一切正常。问题是在 Rails 项目之外的开发中对其进行测试。
我正在使用 cucumber
和 aruba
来测试 CLI 命令是否执行正确的 rails 命令并生成预期的文件。不幸的是,当我尝试测试行为时它失败了,因为没有 rails 文件并且命令需要 运行 在 Rails 项目中才能工作。
我已将 rails 依赖项添加到 gem 规范:
Gem::Specification.new do |spec|
spec.add_development_dependency 'rails', '~> 5.2.4'
end
我考虑过在测试开始时创建一个新的 rails 项目,然后在测试 运行 之后删除它,但这似乎非常不方便。有更好的方法吗?
查看 Thoughbot 的 Appraisal gem:
Appraisal integrates with bundler and rake to test your library against different versions of dependencies in repeatable scenarios called "appraisals."
Here is a guide 了解如何设置它,包括在您的 tests
目录中设置微型 Rails 应用程序。
我们在 WickedPDF 中使用的一项技术是在默认 rake
任务中,在我们 运行 测试之前,删除并生成一个完整的 Rails 应用程序gem.
的 gitignored 子目录
作为高级简化示例of this Rakefile,它看起来像这样:
Rakefile
require 'rake'
require 'rake/testtask'
# This gets run when you run `bin/rake` or `bundle exec rake` without specifying a task.
task :default => [:generate_dummy_rails_app, :test]
desc 'generate a rails app inside the test directory to get access to it'
task :generate_dummy_rails_app do
if File.exist?('test/dummy/config/environment.rb')
FileUtils.rm_r Dir.glob('test/dummy/')
end
system('rails new test/dummy --database=sqlite3')
system('touch test/dummy/db/schema.rb')
FileUtils.cp 'test/fixtures/database.yml', 'test/dummy/config/'
FileUtils.rm_r Dir.glob('test/dummy/test/*') # clobber existing tests
end
desc 'run tests in the test directory, which includes the generated rails app'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
然后,在 test/test_helper.rb 中,我们需要生成的 Rails 应用程序,它加载 Rails
本身及其环境:
test/test_helper.rb
ENV['RAILS_ENV'] = 'test'
require File.expand_path('../dummy/config/environment.rb', __FILE__)
require 'test/unit' # or possibly rspec/minispec
# Tests can go here, or other test files can require this file to have the Rails environment available to them.
# Some tests may need to copy assets/fixtures/controllers into the dummy app before being run. That can happen here, or in your test setup.
您可以通过自定义生成应用程序的命令来跳过不需要的 Rails 部分。例如,您的 gem 可能根本不需要数据库或默认情况下不需要很多东西,因此您可以针对更简单的应用程序自定义命令。可能是这样的:
system("rails new test/dummy --skip-active-record \
--skip-active-storage --skip-action-cable --skip-webpack-install \
--skip-git --skip-sprockets --skip-javascript --skip-turbolinks")
在 WickedPDF 项目中,我们希望在广泛的 "default" Rails 安装范围内进行测试,因此我们不会对命令进行太多自定义,但这可能会产生比您更多的东西需要测试一些生成器任务。
WickedPDF 还针对 Luke 在该主题中建议的 multiple versions of Rails with TravisCI and multiple Gemfiles, but this could also be accomplished with the Appraisal gem 进行了测试。
我正在制作一个 gem 来执行 Rails 命令(例如 rails g model Item
)。当我在 Rails 项目中使用它时,一切正常。问题是在 Rails 项目之外的开发中对其进行测试。
我正在使用 cucumber
和 aruba
来测试 CLI 命令是否执行正确的 rails 命令并生成预期的文件。不幸的是,当我尝试测试行为时它失败了,因为没有 rails 文件并且命令需要 运行 在 Rails 项目中才能工作。
我已将 rails 依赖项添加到 gem 规范:
Gem::Specification.new do |spec|
spec.add_development_dependency 'rails', '~> 5.2.4'
end
我考虑过在测试开始时创建一个新的 rails 项目,然后在测试 运行 之后删除它,但这似乎非常不方便。有更好的方法吗?
查看 Thoughbot 的 Appraisal gem:
Appraisal integrates with bundler and rake to test your library against different versions of dependencies in repeatable scenarios called "appraisals."
Here is a guide 了解如何设置它,包括在您的 tests
目录中设置微型 Rails 应用程序。
我们在 WickedPDF 中使用的一项技术是在默认 rake
任务中,在我们 运行 测试之前,删除并生成一个完整的 Rails 应用程序gem.
作为高级简化示例of this Rakefile,它看起来像这样:
Rakefile
require 'rake'
require 'rake/testtask'
# This gets run when you run `bin/rake` or `bundle exec rake` without specifying a task.
task :default => [:generate_dummy_rails_app, :test]
desc 'generate a rails app inside the test directory to get access to it'
task :generate_dummy_rails_app do
if File.exist?('test/dummy/config/environment.rb')
FileUtils.rm_r Dir.glob('test/dummy/')
end
system('rails new test/dummy --database=sqlite3')
system('touch test/dummy/db/schema.rb')
FileUtils.cp 'test/fixtures/database.yml', 'test/dummy/config/'
FileUtils.rm_r Dir.glob('test/dummy/test/*') # clobber existing tests
end
desc 'run tests in the test directory, which includes the generated rails app'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
然后,在 test/test_helper.rb 中,我们需要生成的 Rails 应用程序,它加载 Rails
本身及其环境:
test/test_helper.rb
ENV['RAILS_ENV'] = 'test'
require File.expand_path('../dummy/config/environment.rb', __FILE__)
require 'test/unit' # or possibly rspec/minispec
# Tests can go here, or other test files can require this file to have the Rails environment available to them.
# Some tests may need to copy assets/fixtures/controllers into the dummy app before being run. That can happen here, or in your test setup.
您可以通过自定义生成应用程序的命令来跳过不需要的 Rails 部分。例如,您的 gem 可能根本不需要数据库或默认情况下不需要很多东西,因此您可以针对更简单的应用程序自定义命令。可能是这样的:
system("rails new test/dummy --skip-active-record \
--skip-active-storage --skip-action-cable --skip-webpack-install \
--skip-git --skip-sprockets --skip-javascript --skip-turbolinks")
在 WickedPDF 项目中,我们希望在广泛的 "default" Rails 安装范围内进行测试,因此我们不会对命令进行太多自定义,但这可能会产生比您更多的东西需要测试一些生成器任务。
WickedPDF 还针对 Luke 在该主题中建议的 multiple versions of Rails with TravisCI and multiple Gemfiles, but this could also be accomplished with the Appraisal gem 进行了测试。