- en
- ja
RSpec 3.5 已发布!
Sam Phippen, Myron Marston 和 Jon Rowe
2016 年 7 月 1 日RSpec 3.5 刚刚发布!鉴于我们对 语义版本控制 的承诺,对于任何已经使用 RSpec 3 的人来说,这应该是一个简单的升级,但如果我们确实引入了任何回归,请告知我们,我们将尽快发布一个包含修复程序的补丁版本。
RSpec 仍然是一个社区驱动的项目,来自世界各地的贡献者参与其中。此版本包含来自 50 多位不同贡献者的 600 多个提交和 150 个合并的拉取请求!
感谢所有帮助使此版本成为现实的人!
重要变更
核心:config.when_first_matching_example_defined
我们通常建议您避免在 spec_helper.rb
中放置仅由部分规范需要的设置逻辑,这样可以最大限度地减少运行隔离单元规范的启动时间。相反,这种设置逻辑可以放在 spec/support
中的某个文件中。需要它的规范文件可以然后要求支持文件并标记示例组以选择加入任何相关的钩子和模块包含,例如
require 'support/db'
RSpec.describe SomeClassThatUsesTheDB, :db do
# ...
end
这可以工作,但始终感觉很不理想,因为需要 require
和 :db
标签才能使其工作。这是每个使用 DB 的规范文件中都会发生的重复。如果我忘记在使用 DB 的规范文件中放入 require 'support/db'
行,我可能会遇到这样的情况:规范文件在单独运行时失败,但在与整个套件一起运行时通过(因为其他规范文件加载了支持文件)。
RSpec 3.5 包含一个新的钩子,在这种情况下效果很好。您无需在每个需要它的规范文件中都要求 support/db
,而是可以配置 RSpec,使其在定义了任何标记为 :db
的示例时加载它
RSpec.configure do |config|
config.when_first_matching_example_defined(:db) do
require 'support/db'
end
end
此新的 when_first_matching_example_defined
钩子会在定义第一个具有匹配元数据的示例时立即触发,允许您根据元数据配置需要加载的内容。当然,这个新的钩子并不局限于此用例,但它是我们期望看到它使用的主要方法之一。
核心:config.filter_run_when_matching
RSpec 元数据系统的一个常见用途是焦点过滤。在 RSpec 3.5 之前,您会像这样配置它
RSpec.configure do |config|
config.filter_run :focus
config.run_all_when_everything_filtered = true
end
然后,您可以用 :focus
标记一个示例或组,让 RSpec 仅运行您标记的内容。当没有任何内容标记为 :focus
时,您希望 RSpec 忽略此过滤器,因此 run_all_when_everything_filtered = true
选项使其执行此操作。
不幸的是,run_all_when_everything_filtered
全局应用于所有过滤(不仅仅是 :focus
过滤),并且它在某些情况下会产生一些令人惊讶的行为。(有关一个示例,请参阅 此问题)。我们意识到,能够将 :focus
设置为条件过滤器会更有意义,因此在 RSpec 3.5 中,您可以这样做
RSpec.configure do |config|
config.filter_run_when_matching :focus
end
使用此配置,:focus
过滤仅在任何示例或组标记为 :focus
时才适用。它还使配置更短、更简单!
核心:按命令行中指定的顺序加载规范文件
RSpec 3.5 现在按命令行参数的顺序加载规范文件和目录。这提供了一种简单的方法,可以以一次性方式对事物进行排序。例如,对于特定的规范运行,如果您希望快速单元规范在缓慢的验收规范之前运行,则可以像这样运行 RSpec
$ rspec spec/unit spec/acceptance --order defined
--order defined
部分仅在您已配置 RSpec 通常随机排序事物时才需要(我们建议将其作为您的默认值)。
核心:共享示例组包含更改
RSpec 长期以来一直支持共享上下文的概念,即为共享上下文帮助程序和钩子而定义的共享示例组。您可以像这样定义共享上下文
RSpec.shared_context "DB support" do
let(:db) { MyORM.database }
# Wrap each example in a transaction...
around do |ex|
db.transaction(:rollback => :always, &ex)
end
# Interleave example begin/end messages in DB logs so it
# is clear which SQL statements come from which examples.
before do |ex|
db.logger.info "Beginning example: #{ex.metadata[:full_description}"
end
after do |ex|
db.logger.info "Ending example: #{ex.metadata[:full_description}"
end
end
要使用此共享上下文,您可以使用 include_context
在组中显式包含它
RSpec.describe MyModel do
include_context "DB support"
end
我们还支持使用匹配元数据在组中隐式包含共享上下文的方法
RSpec.shared_context "DB support", :db do
# ...
end
# ...
RSpec.describe MyModel, :db do
# ...
end
这种方法可以正常工作,但存在几个重大问题
shared_context
的第一个参数("DB support"
)除了标记组的用途外没有其他用途(注释也可以同样实现)。- 一些用户表示惊讶,因为这里的元数据被视为“特殊”,并且没有像应用于普通示例组那样简单地应用于共享示例组。
- 它使得无法将某些元数据附加到共享示例组,这些元数据将自动应用于包含的示例组。例如,您可能希望暂时向所有包含的组添加
:skip
或:focus
元数据。之前无法这样做。 - 没有明显的方法可以使共享示例组自动包含在每个示例组中(例如,对于全局
before
钩子或您想要在任何地方都可用的let
……)。 - 它与模块包含的方式不一致(例如
config.include DBSupport, :db
)。
在 RSpec 3.5 中,我们通过一些更改纠正了这些问题。
新 API:config.include_context
您现在可以在 RSpec.configure
块中定义共享上下文包含
RSpec.configure do |config|
config.include_context "DB support", :db
end
这与模块包含的现有 config.include
API 一致,提供了一种基于元数据包含共享上下文的方法,这种方法不那么令人惊讶,并且可以轻松地将共享上下文包含在所有示例组中(只需不要传递元数据参数)。
新配置选项:config.shared_context_metadata_behavior
我们还添加了一个配置选项,允许您确定如何处理共享上下文元数据
RSpec.configure do |config|
config.shared_context_metadata_behavior = :trigger_inclusion
# or
config.shared_context_metadata_behavior = :apply_to_host_groups
end
以前的值(:trigger_inclusion
)是默认值,仅出于向后兼容性而存在。它将传递给 RSpec.shared_context
的元数据与 RSpec 3.4 及更早版本中的处理方式完全相同:它会触发包含在具有匹配元数据的组中。我们计划在 RSpec 4 中删除对它的支持。
后者的值(:apply_to_host_groups
)选择加入新行为。它不会触发包含在具有匹配元数据的组中,而是将元数据应用于宿主组。例如,您可以通过标记共享上下文来关注使用 DB 的所有组
RSpec.shared_context "DB support", :focus do
# ...
end
期望:respond_to
匹配器的关键字参数支持。
关键字参数已经是一项稳定的语言特性有一段时间了,但 RSpec 缺乏对我们各种匹配器中对关键字参数放置期望的支持。
在 rspec-expectations 3.5 中,我们添加了对检查对象是否响应使用关键字参数的方法的支持。现在,您将能够检查方法的响应签名以查找特定关键字以及传统参数的数量。
expect(my_object).to respond_to(:find).with_keywords(:limit, :offset)
expect(my_object).to respond_to(:find).with(1).argument.and_keywords(:limit, :offset)
我们还在扩展匹配器的现有功能,添加了检查一系列参数或除特定数量之外的无限参数的能力,例如
expect(my_object).to respond_to(:build).with(2..3).arguments
expect(my_object).to respond_to(:build).with_unlimited_arguments
非常感谢 Rob Smith 为将此作为 RSpec 的一部分所付出的努力。
期望:Minitest 集成现在与 Minitest 5.6+ 兼容
虽然 rspec-expectations 通常与 rspec-core 一起使用,但您可以轻松地将其与其他测试框架一起使用。我们提供了与 Minitest 的集成。只需在加载 Minitest 本身之后加载我们的 Minitest 支持即可
require 'rspec/expectations/minitest_integration'
不幸的是,Minitest 5.6 引入了自己的 expect
方法,该方法与我们提供的 expect
方法冲突,并破坏了这种集成。在 rspec-expectations 3.5 中有一个针对此问题的修复程序。
模拟:添加 Minitest 集成
虽然我们长期以来一直在为 rspec-expectations 提供 Minitest 集成,但我们从未为 rspec-mocks 提供过相同级别的简单集成。相反,用户不得不使用我们提供的生命周期钩子将 rspec-mocks 与 Minitest 本身集成。这工作得很好,直到前面提到的 expect
方法被添加到 Minitest 5.6 并破坏了尝试将 rspec-mocks 与 minitest 一起使用的用户的操作。在 rspec-mocks 3.5 中,我们现在为与 Minitest 的使用提供了一流的支持。只需要求我们的集成文件即可
require 'rspec/mocks/minitest_integration'
Rails:对 Rails 5 的支持
这里的主要内容是 RSpec 3.5.0 与 Rails 5 兼容。随着 Rails 5 测试版和候选版本的发布,我们一直在发布 3.5.0 的测试版,以与 Rails 保持同步。由于这是 Rails 的一个主要版本,因此我们使用的某些 API 已经过时。RSpec 并没有进行主要版本发布,因此这只会在一个地方暴露给您,我们的用户:控制器测试。
在 Rails 5 中,assigns
和 assert_template
是“软弃用”。控制器测试本身没有弃用,在您的规范中添加 :type => :controller
仍然 100% 受支持。通过 Rails 3 和 4,在控制器规范中使用 assigns
既普遍又习惯。由于这是 RSpec 的一个次要版本,因此我们对 SemVer 的承诺意味着我们不会破坏您现有的控制器规范。对于大量使用 assigns
的现有 Rails 应用程序,将 rails-controller-testing
添加到您的 Gemfile 将恢复 assigns
和 assert_template
。RSpec 与这个 gem 无缝集成,因此您的控制器规范应该继续工作。
对于新的 Rails 应用程序:我们不建议将 rails-controller-testing
gem 添加到您的应用程序中。Rails 团队和 RSpec 核心团队的官方建议是编写 请求规范。请求规范允许您专注于单个控制器操作,但与控制器测试不同的是,它们涉及路由器、中间件堆栈以及机架请求和响应。这为您的测试增加了真实性,并有助于避免控制器规范中常见的许多问题。在 Rails 5 中,请求规范比 Rails 4 中的请求规范或控制器规范快得多,这要归功于 Rails 提交者团队的 Eileen Uchitelle[^foot_1] 的工作。
我们想讨论的 Rails 5 的另一个重要功能是 ActionCable。不幸的是,RSpec 目前无法提供一种干净的方法来测试 ActionCable。Rails 正在为 ActionCable 开发一种测试类型,计划作为 Rails 5.1 的一部分发布。我们将密切关注它,并在它准备好时开发出解决方案。在此期间,我们建议您通过浏览器以集成的方式测试 ActionCable。
对 Rails 5 的工作代表了 RSpec 核心团队成员的大量投资,并且我们得到了 Rails 提交者和核心团队成员的很大帮助。我们衷心感谢所有参与使这成为可能的人。
统计数据
组合
- 总提交次数: 625
- 合并的拉取请求: 192
- 62 位贡献者:Aaron Stone、Ahmed AbouElhamayed、Al Snow、Alex Altair、Alexander Skiba、Alireza Bashiri、Andrew Kozin(又名 nepalez)、Andrew White、Anton Rieder、Ben Saunders、Benjamin Quorning、Bradley Schaefer、Bruno Bonamin、DarthSim、David Rodríguez、Diogo Benicá、Eliot Sykes、Fernando Seror、Gautam Sawhney、Isaac Betesh、James Coleman、Joe Rafaniello、John Schroeder、Jon Moss、Jon Rowe、Jun Aruga、Kilian Cirera Sant、Koen Punt、Liss McCabe、Marc Ignacio、Martin Emde、Matt Jones、Michele Piccirillo、Miklos Fazekas、Myron Marston、Patrik Wenger、Perry Smith、Peter Swan、Prem Sichanugrist、Rob、Rob Smith、Ryan Beckman、Ryan Clark、Sam Phippen、Scott Bronson、Sergey Pchelintsev、Simon Coffey、Thomas Hart II、Timo Schilling、Tobias Bühlmann、Travis Grathwell、William Jeffries、Wojciech Wnętrzak、Xavier Shay、Yoshihiro Ashida、Yuji Nakayama、Zshawn Syed、chrisarcand、liam-m、mrageh、sleepingkingstudios、yui-knk
rspec-core
- 总提交次数: 194
- 合并的拉取请求: 66
- 18 位贡献者:Alexander Skiba、Alireza Bashiri、Benjamin Quorning、Bradley Schaefer、Jon Moss、Jon Rowe、Matt Jones、Michele Piccirillo、Myron Marston、Patrik Wenger、Perry Smith、Sam Phippen、Simon Coffey、Thomas Hart II、Travis Grathwell、Yuji Nakayama、mrageh、yui-knk
rspec-expectations
- 总提交次数: 83
- 合并的拉取请求: 25
- 14 位贡献者: Alex Altair、Ben Saunders、Benjamin Quorning、Bradley Schaefer、James Coleman、Jon Rowe、Myron Marston、Rob Smith、Sam Phippen、William Jeffries、Yuji Nakayama、Zshawn Syed、chrisarcand、sleepingkingstudios
rspec-mocks
- 总提交次数: 82
- 合并的拉取请求: 28
- 17 位贡献者: Andrew Kozin (又名 nepalez)、Benjamin Quorning、Bradley Schaefer、Bruno Bonamin、David Rodríguez、Isaac Betesh、Joe Rafaniello、Jon Rowe、Kilian Cirera Sant、Marc Ignacio、Martin Emde、Myron Marston、Patrik Wenger、Ryan Beckman、Sam Phippen、Tobias Bühlmann、Yuji Nakayama
rspec-rails
- 总提交次数: 185
- 合并的拉取请求: 47
- 31 位贡献者: Ahmed AbouElhamayed、Al Snow、Andrew White、Anton Rieder、Benjamin Quorning、Bradley Schaefer、DarthSim、David Rodríguez、Diogo Benicá、Eliot Sykes、Fernando Seror、Gautam Sawhney、John Schroeder、Jon Rowe、Jun Aruga、Koen Punt、Liss McCabe、Miklos Fazekas、Myron Marston、Peter Swan、Prem Sichanugrist、Rob、Ryan Clark、Sam Phippen、Scott Bronson、Sergey Pchelintsev、Timo Schilling、Wojciech Wnętrzak、Xavier Shay、Yoshihiro Ashida、Yuji Nakayama
rspec-support
- 总提交次数: 81
- 合并的拉取请求: 26
- 8 位贡献者: Aaron Stone、Bradley Schaefer、Jon Rowe、Myron Marston、Sam Phippen、Yuji Nakayama、liam-m、sleepingkingstudios
文档
API 文档
Cucumber 特性
发布说明
RSpec Core(合并所有 RSpec 3.5.0 的 Beta 版本)
3.5.0 / 2016-07-01
增强功能
- 在二分查找运行结束时打印的复制命令中包含任何
SPEC_OPTS
。(Simon Coffey,#2274)
错误修复
- 正确处理
SPEC_OPTS
环境变量中的--bisect
,以避免无限递归。(Simon Coffey,#2271)
3.5.0.beta4 / 2016-06-05
增强功能
- 默认情况下,从回溯中过滤掉 Bundler 堆栈帧,因为 Bundler 1.12 现在在使用
bundle exec
生成的回溯中包含其自身的帧。(Myron Marston,#2240) - HTML 格式化程序使用异常呈现器来获取错误消息,以与其他格式化程序保持一致。(@mrageh,#2222)
- 按照命令行传递的目录或文件的顺序加载规范文件,这使得在一次性方式下使某些规范在其他规范之前运行变得容易。例如,
rspec spec/unit spec/acceptance --order defined
将在接受规范之前运行单元规范。(Myron Marston,#2253) - 添加新的
config.include_context
API 用于配置示例组中共享上下文的全局或过滤后的包含。(Myron Marston,#2256) - 添加新的
config.shared_context_metadata_behavior = :apply_to_host_groups
选项,该选项使共享上下文元数据被所有主机组和示例的元数据哈希继承,而不是根据传递的元数据配置隐式自动包含。(Myron Marston,#2256)
错误修复
- 修复
--bisect
,使其适用于之前由于所有规范位置都作为 CLI 参数传递而导致“参数列表过长错误”的大型规范套件。(Matt Jones,#2223)。 - 修复已弃用的
:example_group
过滤,使其正确地应用于匹配的示例组。(Myron Marston,#2234) - 修复由 JRuby 上的 Java 回溯引起的
NoMethodError
。(Michele Piccirillo,#2244)
3.5.0.beta3 / 2016-04-02
增强功能
- 添加新的
config.filter_run_when_matching
API,旨在替换config.filter_run
和config.run_all_when_everything_filtered
的组合。(Myron Marston,#2206)
错误修复
- 使用编码字符串逻辑进行源代码提取。(Jon Rowe,#2183)
- 修复持续时间格式化帮助程序中的舍入问题。(Fabersky、Jon Rowe,#2208)
- 修复失败代码片段提取,以便以
end
结尾的def-end
代码片段可以正确提取。(Yuji Nakayama,#2215)
3.5.0.beta2 / 2016-03-10
增强功能
- 删除不必要的
:execution_result
示例组元数据,节省了一些内存。(Myron Marston,#2172) - 将使用
config
注册的挂钩应用于先前定义的组。(Myron Marston,#2189) RSpec::Core::Configuration#reporter
现在是 SemVer 下的公共 API。(Jon Rowe,#2193)- 添加新的
config.when_first_matching_example_defined
挂钩。(Myron Marston,#2175)
3.5.0.beta1 / 2016-02-06
增强功能
- 添加
RSpec::Core::ExampleGroup.currently_executing_a_context_hook?
,主要用于 rspec-rails。(Sam Phippen,#2131)
错误修复
- 确保
MultipleExceptionError
不包含对自身的递归引用。(Sam Phippen,#2133)
RSpec Expectations(包括所有 RSpec 3.5.0 的 Beta 版本)
3.5.0 / 2016-07-01
自 beta4 以来没有面向用户的更改
3.5.0.beta4 / 2016-06-05
错误修复
- 修复
include
匹配器,使其为哈希提供有效的差异。(Yuji Nakayama,#916)
3.5.0.beta3 / 2016-04-02
增强功能
- 使
rspec/expectations/minitest_integration
在 Minitest::Spec 5.6+ 上工作。(Myron Marston,#904) - 为
have_attributes
匹配器添加一个别名having_attributes
。(Yuji Nakayama,#905) - 当块被误用时,改进
change
匹配器错误消息。(Alex Altair,#908)
3.5.0.beta2 / 2016-03-10
增强功能
- 添加通过
RSpec::Configuration#on_potential_false_positives = :raise
遇到假阳性时引发错误的能力。(Jon Rowe,#900) - 当使用自定义匹配器 DSL 时,支持
match
方法的新notify_expectation_failures: true
选项,以允许将期望失败作为正常方式引发,而不是将其转换为matches?
的false
返回值。(Jon Rowe,#892)
错误修复
- 允许
should
弃用检查在BasicObject
上工作。(James Coleman,#898)
3.5.0.beta1 / 2016-02-06
增强功能
- 使自定义匹配器 DSL 中的
match_when_negated
支持在匹配逻辑中使用期望。(Chris Arcand,#789)
错误修复
- 从传递的否定期望(例如
expect("foo").not_to eq "bar"
)返回true
,如预期的那样,以便它们在match
或match_when_negated
块中使用时能正常工作。(Chris Arcand,#789)
RSpec Mocks(包括所有 RSpec 3.5.0 的 Beta 版本)
3.5.0 / 2016-07-01
增强功能
- 提供
RSpec::Mocks::MessageExpectation
的良好字符串表示。(Myron Marston,#1095)
3.5.0.beta4 / 2016-06-05
增强功能
- 将
and_throw
添加到任何实例处理。(Tobias Bühlmann,#1068)
3.5.0.beta3 / 2016-04-02
增强功能
- 当尝试使用不支持的
allow(...).to receive(...).ordered
时发出警告。(Jon Rowe,#1000) - 添加
rspec/mocks/minitest_integration
,以正确地将 rspec-mocks 与 minitest 集成。(Myron Marston,#1065)
3.5.0.beta2 / 2016-03-10
增强功能
- 改进在纯测试替身上使用
and_wrap_original
时显示的错误消息。(betesh,#1063)
错误修复
- 修复了阻止
receive_message_chain(...).with(...)
在“任何实例”模拟上正确工作的问题。(Jon Rowe,#1061)
3.5.0.beta1 / 2016-02-06
错误修复
- 允许
any_instance_of(...).to receive(...)
多次使用and_yield
。(Kilian Cirera Sant,#1054) - 允许从
rspec-mocks
匹配器继承的匹配器用于allow
。(Andrew Kozin,#1056) - 阻止在部分替身上模拟
respond_to?
导致无限递归。(Jon Rowe,#1013) - 阻止别名方法在使用
any_instance
模拟后消失(来自 #1043 的回归)。(Joe Rafaniello,#1060)
RSpec Support(包括所有 RSpec 3.5.0 的 Beta 版本)
3.5.0 / 2016-07-01
自 beat4 以来没有面向用户的更改
3.5.0.beta4 / 2016-06-05
增强功能:* 改进 MethodSignature
以更好地支持关键字参数。(#250,Rob Smith)。
3.5.0.beta3 / 2016-04-02
错误修复
- 修复
EncodedString
以正确处理 JRuby 上的String#split
在字符串包含无效字节时的行为。(Jon Rowe,#268) - 修复
ObjectFormatter
,以便格式化不响应#inspect
的对象(例如BasicObject
)不会导致NoMethodError
。(Yuji Nakayama,#269) - 修复
ObjectFormatter
,以便格式化递归数组或哈希不会导致SystemStackError
。(Yuji Nakayama,#270,#272)
3.5.0.beta2 / 2016-03-10
没有面向用户的更改。
3.5.0.beta1 / 2016-02-06
脚注
[^foot_1]: 另请参阅 Eileen 关于请求规范性能的 演讲