RSpec 3.1 发布了!
Myron Marston
2014 年 9 月 4 日RSpec 3.1 刚刚发布!考虑到我们对 语义化版本控制 的承诺,对于任何已经使用 RSpec 3.0 的人来说,这应该是一个微不足道的升级。但是,如果我们确实引入了任何回归,请告诉我们,我们会尽快发布一个包含修复的补丁版本。
RSpec 仍然是一个社区驱动的项目,拥有来自世界各地的贡献者。此版本包含来自 47 位不同贡献者的 190 个 pull 请求的 647 次提交。
感谢所有帮助使这次发布成为现实的人!
值得注意的变化
核心:回溯过滤更改
在 RSpec 2.x 和 RSpec 3.0 中,默认的回溯过滤配置从打印的回溯中排除了 gems 中的代码行。我们 收到了一些反馈,认为这没有帮助,并且已经从默认的回溯过滤器模式中删除了 /gems/
。在 RSpec 3.1 中,来自 gems 的代码行将包含在回溯中,但来自 RSpec 本身的代码行将继续被排除。当然,如果你仍然想要排除 gems,你可以轻松地自己添加这个模式。
# spec/spec_helper.rb
RSpec.configure do |config|
config.backtrace_exclusion_patterns << /gems/
end
此外,我们添加了一个新的 API,可以轻松地过滤掉一个或多个特定的 gems。
# spec/spec_helper.rb
RSpec.configure do |config|
config.filter_gems_from_backtrace "rack", "rake"
end
核心:新的 --exclude-pattern
选项
RSpec 3.1 有一个新的 --exclude-pattern
选项,它是 --pattern
的反义词。这允许你排除特定的文件,例如,你可以加载和运行所有 spec 文件,除了来自特定目录的文件。
rspec --pattern "spec/**/*_spec.rb" --exclude-pattern "spec/acceptance/**/*_spec.rb"
rake 任务定义 API 也支持这个选项,因此可以轻松地定义运行所有 specs 除了来自一个目录的 specs 的任务。
# Rakefile
require 'rspec/core/rake_task'
desc "Run all but the acceptance specs"
RSpec::Core::RakeTask.new(:all_but_acceptance) do |t|
t.exclude_pattern = "spec/acceptance/**/*_spec.rb"
end
感谢 John Gesimondo 建议并 实现 此新功能!
核心:现在可以独立使用,无需配置
RSpec 在 RSpec 2.0 中被拆分为单独的 gems(核心、期望和模拟),这允许用户 混合和匹配 RSpec 的各个部分 与其他测试库,如 Minitest。Tom Stuart 指出,仅仅使用 rspec-core 并不像预期的那样容易。具体来说,在 RSpec 3.0 及之前版本中,如果你没有明确配置 rspec-core 不要使用 rspec-expectations 和 rspec-mocks,它会假设它们可用,尝试加载它们,并在它们不可用时报错。
在 RSpec 3.1 中,我们已经纠正了这个问题。rspec-expectations 和 rspec-mocks 仍然会默认使用(如果可用),但如果它们不可用,并且你没有进行任何配置,rspec-core 将正常工作。
感谢 Sam Phippen 实现 了此改进。
核心:警告标志不再在生成的文件中默认设置为 true
在 RSpec 3.0 中,我们将 --warnings
放入生成的 .rspec
文件中。我们这样做是为了鼓励 gem 作者使他们的 gems 无警告(因为发出警告的 gems 会阻止用户使用 Ruby 的警告模式)。但是,rails 生态系统通常没有努力实现无警告代码,在新的 rails 项目中,这导致了大量令人困惑的警告。
在 RSpec 3.1 中,我们从社区反馈中吸取了教训,并从生成的 .rspec
文件中删除了 --warnings
。在非 rails 项目中,rspec --init
将在 spec_helper.rb
中推荐设置的注释部分包含 config.warnings = true
。
感谢 Andrew Hooker 做了这个更改。
期望:新的 have_attributes
匹配器
这个新的匹配器使根据对象的属性来匹配对象变得容易。
Person = Struct.new(:name, :age)
person = Person.new("Coen", 3)
expect(person).to have_attributes(name: "Coen", age: 3)
它也被别名为 an_object_having_attributes
,这在组合匹配器表达式中特别有用。
people = [Person.new("Coen", 3), Person.new("Daphne", 2)]
expect(people).to match([
an_object_having_attributes(name: "Coen", age: 3),
an_object_having_attributes(name: "Daphne", age: 2)
])
它也可以用作消息期望的实参匹配器。
expect(email_gateway).to receive(:send_receipt).with(
an_object_having_attributes(email: "foo@example.com")
)
感谢 Adam Farhi 实现 了这个新的匹配器。
期望:块匹配器现在可以在复合表达式中使用
RSpec 3.0 获得了使用 复合匹配器表达式 的能力。但是,它不适用于块期望,因为我们有一些内部更改需要进行,以确保块只执行一次,正如预期的那样。我们在 3.1 中解决了这个问题,允许像这样的表达式。
x = y = 0
expect {
x += 1
y += 2
}.to change { x }.to(1).and change { y }.to(2)
期望:新的 define_negated_matcher
API
这个新的 API 提供了一种方法来定义现有匹配器的否定版本。
# define a negated form of `include`...
RSpec::Matchers.define_negated_matcher :exclude, :include
# ...which allows you to write:
expect(odd_numbers).to exclude(14)
# ...rather than:
expect(odd_numbers).not_to include(14)
它本身并没有给你带来什么帮助。但是,在处理组合或复合匹配器表达式时,它非常有用。
adults = Town.find("Springfield").adults
marge = Character.find("Marge")
bart = Character.find("Bart")
expect(adults).to include(marge).and exclude(bart)
感谢 Adam Farhi 帮助 实现 了此功能。
期望:自定义匹配器链式修饰符现在包含在生成的描述中
自定义匹配器 DSL 允许你使用 chain
来定义一个流畅的接口。
RSpec::Matchers.define :be_smaller_than do |max|
chain :and_bigger_than do |min|
@min = min
end
match do |actual|
actual < max && actual > @min
end
end
# usage:
expect(10).to be_smaller_than(20).and_bigger_than(5)
在 RSpec 2.x 和 3.0 中,链式部分没有包含在失败消息中。
Failure/Error: expect(5).to be_smaller_than(10).and_bigger_than(7)
expected 5 to be smaller than 10
RSpec 3.1 可以将链式部分包含在失败消息中。
Failure/Error: expect(5).to be_smaller_than(10).and_bigger_than(7)
expected 5 to be smaller than 10 and bigger than 7
…但只有在你使用配置选项启用此行为的情况下。
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
end
此配置选项默认设置为 false
,以保证向后兼容。我们计划在 RSpec 4 中始终启用它。
感谢 Dan Oved 实现 了此改进!
模拟:新的 *_spy
方法
RSpec 2.14 添加了对将测试替身用作间谍的支持,这允许你在事后设置一个关于消息是否接收到的期望。
spy = double(:foo => nil)
# do something with spy
expect(spy).to have_received(:foo)
请注意,我们在这里对 foo
进行了存根。这是必要的,因为替身默认情况下是严格的,这意味着当它们收到意外的消息时会抛出错误。不幸的是,这会强迫你进行一些重复,因为你必须两次声明该方法(在之前进行存根,并在之后期望它被接收)。
你可以使用 as_null_object
来解决这个问题,它使替身变得“松散”而不是严格,允许它接收任何消息。
spy = double.as_null_object
# do something with spy
expect(spy).to have_received(:foo)
这种模式非常有用,因此在 RSpec 3.1 中,我们添加了新的方法来声明间谍。
spy(...) # equivalent to double(...).as_null_object
instance_spy(...) # equivalent to instance_double(...).as_null_object
class_spy(...) # equivalent to class_double(...).as_null_object
object_spy(...) # equivalent to object_double(...).as_null_object
感谢 Justin Searls 提出了这个问题,并感谢 Sam Phippen 实现了 这些新方法。
模拟:新的 and_wrap_original
API
这个新的 API 允许你轻松地装饰特定对象上的特定现有方法,只在当前示例的持续时间内。原始方法作为第一个参数传递给你的块(在实际方法调用参数之前)。
allow(api_client).to receive(:fetch_users).and_wrap_original do |original_method, *args|
original_method.call(*args).first(10) # truncate the response to the first 10 users
end
感谢 Jon Rowe 实现了 此功能。
Rails:Rails 4.2 支持
rspec-rails 3.1 将正式支持 Rails 4.2。Aaron Kromer 一直在努力使 RSpec 3.1 为 Rails 4.2 做好准备。这包括一个由 Abdelkader Boudih 提供 的 ActiveJob 生成器。
Rails:生成的 rails_helper.rb
默认不再自动加载 spec/support
文件
Aaron 还 做了一个小改动,用于生成 rails_helper.rb
。以前,它包含一些代码,这些代码会自动加载 spec/support
下的所有文件。该代码仍然存在,但现在被注释掉了。我们发现,手动需要所需的 support 文件,而不是始终加载所有文件,这有助于防止加载时膨胀。
当然,如果你喜欢以前方法的方便性,这是一个合理的权衡,你可以轻松地取消注释这部分代码。
统计
rspec-core
- 总提交: 176
- 合并的 pull 请求: 50
- 20 位贡献者:Aaron Kromer, Alex Tan, Andrew Hooker, Christian Treppo, Colin Jones, Daniela Wellisz, Dominic Muller, Evgeny Zislis, Gary Fleshman, Jimmy Cuadra, John Gesimondo, Jon Rowe, Mark Lorenz, Max Lincoln, Myron Marston, Paul Cortens, Prem Sichanugrist, Sam Phippen, Su Zhang (張甦), tomykaira
rspec-expectations
- 总提交: 149
- 合并的 pull 请求: 40
- 14 位贡献者:Aaron Kromer, Abdelkader Boudih, Adam Farhi, Alex Sunderland, Chris Griego, Dennis Taylor, Hao Su, Jon Rowe, Myron Marston, Pritesh Jain, Sam Phippen, Xavier Shay, fimmtiu, oveddan
rspec-mocks
- 总提交: 118
- 合并的 pull 请求: 39
- 13 位贡献者:Aaron Kromer, Chris Griego, Dennis Taylor, Eugene Kenny, Igor Kapkov, Jimmy Cuadra, Jon Rowe, Karthik T, Myron Marston, Oliver Martell Núñez, Sam Phippen, Thomas Brand, Xavier Shay
rspec-rails
- 总提交: 137
- 合并的 pull 请求: 38
- 16 位贡献者:Aaron Kromer, Abdelkader Boudih, Alex Rothenberg, Andre Arko & Doc Ritezel, André Arko, Bradley Schaefer, Diego Plentz, Jon Rowe, Josh Kalderimis, Juan González, Kosmas Chatzimichalis, Michael E. Gruen, Myron Marston, Sam Phippen, Thomas Kriechbaumer, joker1007
rspec-support
- 总提交: 67
- 合并的 pull 请求: 23
- 8 位贡献者:Aaron Kromer, Ben Langfeld, Jimmy Cuadra, Jon Rowe, Myron Marston, Pritesh Jain, Sam Phippen, Xavier Shay
文档
API 文档
- http://rubydoc.info/gems/rspec-core
- http://rubydoc.info/gems/rspec-expectations
- http://rubydoc.info/gems/rspec-mocks
- http://rubydoc.info/gems/rspec-rails
Cucumber 功能
- http://relishapp.com/rspec/rspec-core
- http://relishapp.com/rspec/rspec-expectations
- http://relishapp.com/rspec/rspec-mocks
- http://relishapp.com/rspec/rspec-rails
发布说明
rspec-core-3.1.0
增强功能
- 更新
rspec --init
生成的文件,以便在spec_helper
的注释部分启用警告,而不是在.rspec
中,因此用户必须有意识地选择该设置。(Andrew Hooker, #1572) - 更新
rspec --init
生成的spec_helper
,以便它设置新的 rspec-expectationsinclude_chain_clauses_in_custom_matcher_descriptions
配置选项(在 RSpec 4 中默认启用),并设置 rspec-mocksverify_partial_doubles
选项(在 RSpec 4 中也默认启用)。(Myron Marston, #1647) - 为示例代理对象(在 around 钩子中使用)提供
inspect
输出,这些对象看起来不像 proc。(Jon Rowe, #1620) - 从
rspec/core/rake_task.rb
中删除一些不必要的require
语句,使它更轻量级。(Myron Marston, #1640) - 允许 rspec-core 在没有安装 rspec-mocks 或 rspec-expectations 的情况下使用,无需任何用户配置。(Sam Phippen, Myron Marston, #1615)
- 默认情况下不要从回溯中过滤掉 gems。(RSpec gems 仍然会被过滤)。用户反馈表明,在默认回溯中包含 gems 会很有用。(Myron Marston, #1641)
- 添加新的
config.filter_gems_from_backtrace "rack", "rake"
API,可以轻松地从回溯中过滤掉命名的 gems。(Myron Marston, #1682) - 修复默认回溯过滤器,以便在将 RSpec 安装为 bundler
:git
依赖项时排除 RSpec 二进制文件。(Myron Marston, #1648) - 简化 rake 任务生成的命令,使其不再包含不必要的
-S
。(Myron Marston, #1559) - 添加
--exclude-pattern
CLI 选项、config.exclude_pattern =
配置选项和task.exclude_pattern =
rake 任务配置选项。匹配的文件将被排除。(John Gesimondo, Myron Marston, #1651, #1671) - 当 around 钩子无法执行示例时,将其标记为待定(而不是通过),以便用户了解示例实际上没有运行。(Myron Marston, #1660)
- 从标准库中删除对
FileUtils
的依赖,以便用户不会收到误报,即他们的代码依赖于它,但他们没有要求它。(Sam Phippen, #1565)
错误修复
- 修复 rake 任务
t.pattern =
选项,以便当它不匹配任何文件时,不会运行所有 specs,方法是将--pattern
选项传递给rspec
命令,而不是解析文件列表并单独传递文件。(Evgeny Zislis, #1653) - 修复 rake 任务默认模式,使其能够正确地跟随符号链接。(Myron Marston, #1672)
- 修复与
rspec
命令一起使用的默认模式,使其能够正确地跟随符号链接。(Myron Marston, #1672) - 更改我们为示例组类分配常量名称的方式,以避免
describe "Core"
出现的问题。(Daniela Wellisz, #1679) - 处理渲染异常,这些异常的编码与它们的原始源文件的编码不同。(Jon Rowe, #1681)
- 即使是共享示例组中的部分,也允许访问失败示例的 message_lines,但不要显示颜色。(tomykaira,#1689)
rspec-expectations-3.1.0
增强功能
- 添加
have_attributes
匹配器,如果实际的属性值与预期的属性哈希匹配,则通过:Person = Struct.new(:name, :age)
person = Person.new("Bob", 32)
expect(person).to have_attributes(:name => "Bob", :age => 32)
。(Adam Farhi,#571) - 扩展了对块匹配器的复合匹配器支持,适用于以下情况:
expect { ... }.to change { x }.to(3).and change { y }.to(4)
。(Myron Marston,#567) - 当启用新的
include_chain_clauses_in_custom_matcher_descriptions
配置选项时,将链式方法包含在自定义匹配器描述和失败消息中。(Dan Oved,#600) - 将
thrice
修饰符添加到yield_control
匹配器作为exactly(3).times
的同义词。(Dennis Taylor,#615) - 添加
RSpec::Matchers.define_negated_matcher
,它定义了命名匹配器的否定版本。(Adam Farhi,Myron Marston,#618) - 文档化并支持对
contain_exactly
/match_array
的否定。(Jon Rowe,#626)。
错误修复
- 将私有
LegacyMacherAdapter
常量重命名为LegacyMatcherAdapter
以修复拼写错误。(Abdelkader Boudih,#563) - 修复
all
匹配器,以便在与不可枚举对象匹配时能够正确失败(而不是引发NoMethodError
)。(Hao Su,#622)
rspec-mocks-3.1.0
增强功能
- 添加间谍方法(
spy
、ìnstance_spy
、class_spy
和object_spy
),这些方法创建双重对象作为空对象,用于在测试中进行间谍。(Sam Phippen,#671) - 当与验证双重对象和部分双重对象一起使用时,
have_received
匹配器将正确地引发“未实现”错误。(Xavier Shay,#722) - 允许在
with
预期中使用匹配器代替关键字参数。(Xavier Shay,#726) - 将
thrice
修饰符添加到消息预期接口中,作为exactly(3).times
的同义词。(Dennis Taylor,#753) - 添加更多
thrice
同义词,例如.at_least(:thrice)
、.at_most(:thrice)
、receive(...).thrice
和have_received(...).thrice
。(Jon Rowe,#754) - 为部分双重对象添加
and_wrap_original
修饰符,以修改方法的响应。(Jon Rowe,#762)
Bugfixes
- 从
any_instance
记录器中删除any_number_of_times
,这些记录器错误地导致文档中提到该方法。(Jon Rowe,#760) - 防止在 Ruby 2.0 上将包含的模块检测为预置的模块。(Eugene Kenny,#771)
rspec-rails-3.1.0
增强功能
- 切换到在规范生成器中使用
have_http_status
匹配器。(Aaron Kromer,#1086) - 更新
rails_helper
生成器,允许用户选择加入自动加载spec/support
文件,而不是强制执行。(Aaron Kromer,#1137) - 包含
ActiveJob
的生成器。(Abdelkader Boudih,#1155) - 通过不在生成的
rails_helper
中加载与 ActiveRecord 相关的设置,来改善对非 ActiveRecord 应用程序的支持。(Aaron Kromer,#1150) - 删除 Ruby 警告作为建议的配置。(Aaron Kromer,#1163)
错误修复
- 修复 Rails 4.2 的控制器路由查找。(Tomohiro Hashidate,#1142)