RSpec 是Ruby的一个行为驱动开发(BDD)工具,当前的版本是 2.10。根据其入门文档,安装好之后,可以使用 rspec
命令来运行“测试”。但在某些情况下,如果参数较多,使用该命令并不方便;幸运的是,我们可以将 RSpec 添加到 Rake 任务中来运行。
根据文档,只要将如下代码添加到 Rakefile 中即可
require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :default => :spec
观察一下这段代码的内容:
首先加载了 rspec/core/rake_task 文件,该文件并不在 rspec 这个 gem 中,而是在 rspec-core 中,文件路径为 lib/rspec/core/rake_task.rb 。
然后创建了一个 RSpec::Core::RakeTask
实例。 查看其实现可知,它是 ::Rake::TaskLib
的子类。RSpec::Core::RakeTask#initialize
的实现如下:
def initialize(*args) @name = args.shift || :spec @pattern, @rcov_path, @rcov_opts, @ruby_opts, @rspec_opts = nil, nil, nil, nil, nil @warning, @rcov = false, false @verbose, @fail_on_error = true, true yield self if block_given? @rcov_path ||= 'rcov' @rspec_path ||= 'rspec' @pattern ||= './spec{,/*/**}/*_spec.rb' desc("Run RSpec code examples") unless ::Rake.application.last_comment task name do RakeFileUtils.send(:verbose, verbose) do if files_to_run.empty? puts "No examples matching #{pattern} could be found" else begin puts spec_command if verbose success = system(spec_command) rescue puts failure_message if failure_message end raise("#{spec_command} failed") if fail_on_error unless success end end end end
从代码中可以看出,该方法其实很简单,就是读取和设置了一系列默认属性(比如 pattern 设置为 ./spec 目录下的所有以 _spec.rb 结尾的文件),然后使用Rake中常见的 desc
、task
等方法创建了任务。而在 Rakefile 中的 RSpec::Core::RakeTask.new(:spec)
只不过是创建了一个叫 spec 的任务而已。
最后,使用 task :default => :spec
会将名为 spec 的任务设置为默认的,这样在命令行下使用 rake
就会执行 rake sepc
。
再来查看 RSpec::Core::RakeTask#initialize
的 yield self if block_given?
,可以看出,该方法处理了代码块参数,因此可以传递代码块来设置一些属性。比如可以新建一个任务,只运行 ./rspec/user_spec.rb:
desc 'Run User Rspec' RSpec::Core::RakeTask.new(:user_spec) do |t| t.pattern = './rspec/user_spec.rb' end
这样在命令行下执行 rake use_spec
即可
用rake执行不会读取.spec中的配置
需要在rakefile中设置
ENV['SPEC_OPTS'] ||= '' ENV['SPEC_OPTS'] += ' --format html --out spec/report/results.html'