我从来没有真正相信过从Ruby on Rails中的Test :: Unit切换到RSpec所获得的优势(尽管不时阅读有关RSpec的信息)。
大多数Rails项目似乎都在使用RSpec呢?
(一些代码示例清楚地表明了一个相对于另一个的优势,将不胜感激)
我从来没有真正相信过从Ruby on Rails中的Test :: Unit切换到RSpec所获得的优势(尽管不时阅读有关RSpec的信息)。
大多数Rails项目似乎都在使用RSpec呢?
(一些代码示例清楚地表明了一个相对于另一个的优势,将不胜感激)
Answers:
这很大程度上取决于口味,大多数测试工具都值得他们的支持。我个人偏爱使用RSpec而不是Test :: Unit,因为a)测试的输出和布局专注于被测试对象应该做什么(与代码相反),以及b)说“ X应该是Y”对我来说,比“断言X谓词Y”更有意义。
为了给您提供以上几点的上下文,这是两个功能等效的单元测试的输出/源代码的比较(相当拟定),一个使用RSpec编写,另一个使用Test :: Unit。
被测代码
class DeadError < StandardError; end
class Dog
def bark
raise DeadError.new "Can't bark when dead" if @dead
"woof"
end
def die
@dead = true
end
end
测试::单位
require 'test/unit'
require 'dog'
class DogTest < Test::Unit::TestCase
def setup
@dog = Dog.new
end
def test_barks
assert_equal "woof", @dog.bark
end
def test_doesnt_bark_when_dead
@dog.die
assert_raises DeadError do
@dog.bark
end
end
end
规范
require 'rspec'
require 'dog'
describe Dog do
before(:all) do
@dog = Dog.new
end
context "when alive" do
it "barks" do
@dog.bark.should == "woof"
end
end
context "when dead" do
before do
@dog.die
end
it "raises an error when asked to bark" do
lambda { @dog.bark }.should raise_error(DeadError)
end
end
end
测试::单位输出(我可以做到的全部)
Ξ code/examples → ruby dog_test.rb --verbose
Loaded suite dog_test
Started
test_barks(DogTest): .
test_doesnt_bark_when_dead(DogTest): .
Finished in 0.004937 seconds.
RSpec输出(文档格式化程序)
Ξ code/examples → rspec -fd dog_spec.rb
Dog
when alive
barks
when dead
raises an error when asked to bark
Finished in 0.00224 seconds
2 examples, 0 failures
2 tests, 2 assertions, 0 failures, 0 errors
PS:我认为Berin(先前的响应者)正在将Cucumber(它起源于RSpec项目但独立)和RSpec的角色混为一谈。Cucumber是用于BDD样式的自动验收测试的工具,而RSpec是用于测试的代码库,可以并且可以在单元,集成和功能级别上使用。因此,使用RSpec并不排除单元测试-只是您将单元测试称为“规范”。
最近,似乎Cucumber在Rails社区中获得了更多的支持。这是我在接受RSpec主管采访时(从旧的Ruby on Rails播客中)听到的概括性论点。
在当时的敏捷社区中,“测试驱动开发”取得了巨大的推动,重点是首先进行测试以证明您必须进行某些更改。这在哲学上有问题。本质上,测试是一种验证您的实现正确的方法,那么您如何看待驾驶设计呢?RSpec的负责人推测您是先指定的,如果该规范还检查了实现的结果,那不是很好吗?
简单的重命名assert
,以should
有助于集中在正确的方式来写规范人的思想,思考设计。但是,这只是等式的一部分。
更重要的是,由于许多TDD的信奉者声称测试记录了设计,因此大多数文档充其量是最差的。对于不熟悉该语言的非开发人员而言,测试是相当不透明的。即使到那时,通过阅读大多数测试,该设计也不会立即显现出来。
因此,作为第二个目标,RSpec设计了一种从规范中生成书面文档的方法。正是这个书面规范使RSpec在简单的Test :: Unit上具有优势,以驱动应用程序的设计。当可以同时记录和验证设计一致性时,为什么要多次编写?
我的理解是,Cucumber受益匪浅,可以从RSpec中学习,并且可以更好地完成次要目标,而又不会失去主要目标(能够从规范中测试实现)。黄瓜用相当像英文的API来做到这一点,非程序员可以合理地使用它。他们可能需要程序员的一些帮助来填写新验证方法的一些定义,但是它的目的是可扩展的。
底线是RSpec / Cucumber不应完全取代单元测试。它们可能更适合于记录和验证您的设计-但是仍有一些实现测试需要完成,尤其是那些源自实现而不是应用程序设计的细微错误。它确实减少了您必须编写的测试数量。