ruby-china 的代码中现在有两套测试代码,Test::Unit 部分是我写的,另外有部分 Rspec,都是刚起步。一套代码不应该有两个测试框架,所以要定一下用哪套。看见 Rspec 呼声蛮高的,呼吁大家投个票(回帖),希望用哪套测试框架。如果用 Rspec 我可以把现在 Test::Unit 的测试改写过去。
我得表明一下:I hate Rspec.
理由:无意义的 DSL,在我看来仅仅是把 assert 写成 should,把 test 写成 it。写 Rspec 的人大多跟风,没有写过 Test::Unit,毫无理由的忽视 Test::Unit,Rspec 还要增加维护成本。DHH 坚决使用 Test::Unit,是我的支援。
#2 楼 @southwolf DSL 的魅力是简化本来复杂的逻辑。但是 Test::Unit 本身就不复杂,非常直观,倒是转到 Rspec 要把思维扭个弯。然后这两套测试组件的可读性取决于熟练程度。
RSpec 部分是我加的。
Test::Unit 如何简单的实现 Rspec 里的 shared examples 和 shared context?
我在早前一个帖子里回复过,我在这里再回复一下——
我一般写 library,用 MiniTest(Test::Unit)。写应用程序,用 RSpec,主要是 RSpec 的 DSL 比 Test::Unit 要简练。当然,MiniTest 有个 Spec 的库可以用,不过我几乎没怎么用过,不知道是否支持 shared examples/context。
Module ContentExample
def test_should_acts_as_content
assert ...
end
end
Class PostTest < ActiveSupport::TestCase
include ContentExample
end
shared context 直接写个 method 调用好了(只有 let)。
这个例子没有 rspec 的 shared_examples 和 shared_context 强大,但我觉得这个优点不足以驱逐 Rails 自带的测试框架,因为我见过 Rails 升级时 Rspec 的各种不兼容(Rspec 竟然有两个大版本)。
还有一个强烈反感 Rspec 的是因为 Cucumber,同样的测试覆盖度,用上 Cucumber 代码量要大 5 倍,很多还是工具生成的,我想到 Java。而偏偏 Rspec 社区就和 Cucumber 绑上了。Rspec 的书上来就写 Cucumber,然后社区一直怂恿:你用 Rspec?你喜欢 BDD?来吧,用 Cucumber 让你的 BDD 更酷。开发者主导的项目,Cucumber 除了给脚上绑上铅块我看不到任何好处,而且我很怀疑产品设计人员根本不会写 Cucumber,最终就是 BDD 爱好者自娱自乐。
所以都用嘛。。要改变自己的习惯去适应别人挺麻烦的。。 我刚才试过了,rake test 执行 Test::Unit,rspec spec 执行 rspec,不冲突。 如果执行两次测试太麻烦,可以只执行自己这一方的测试,也可以加个 task 来执行上面那两个命令。 rspec 有一种概念 steak(https://github.com/cavalle/steak ),就是用 rspec+capybara 取代 cucumber 来做集成测试。
rake test 现在有个错误,不过不是因为和 rspec 冲突引起的
test_should_read_topic_after_user_reply_topic ERROR
undefined method `user_readed?'
看大家都在反对 cucumber,这几天我也在思考 cucumber 存在的意义。 我用 cucumber 主要是帮助我梳理思路,用汉语写的过程就是在思考,考虑好了之后写 step def 如果熟悉了其实很容易,一两分钟就可以搞定,而且写过的 step 还可以反复利用。 不过我没有大项目经验。。
关于“不正确的 Cucumber 使用方式”,可不可以再指点我一些经验? https://github.com/cqpx/ruby-china/blob/bdd/features/marks.feature https://github.com/cqpx/ruby-china/blob/bdd/features/step_definitions/marks_steps.rb
昨天提到的问题是因为我当时赶工没有去改一个小地方所以 copy&paste 了一段代码过来 通常情况我不会这样做,我会写一个 Scenario 来测某个流程
Scenario: 可以登录
Given 存在用户"larry",Email是"[email protected]",密码是"iwonttellyou"
When 访问首页
And 点击"登录"
And 在"用户名"输入"larry"
And 在"密码"输入"iwonttellyou"
And 点击"登陆"
Then 能看到"我的主页"
然后其他要用到这个流程的地方我就写一个 step 来调用,就不用 copy&paste 了
When /^"([^"]*)"登录$/ do |arg1|
step %{存在用户"#{arg1}",Email是"#{arg1}@example.com",密码是"iwonttellyou"}
step %{访问首页}
step %{点击"登录"}
step %{在"用户名"输入"#{arg1}"}
step %{在"密码"输入"iwonttellyou"}
step %{点击"登陆"}
end
其他地方就只需要用这一句 When xxx 登录
Scenario: 可以回帖
Given 存在节点"问候"
When "larry"登录
And 在节点"问候"下发新帖"你好 world",内容是"@sergey 咋样啊? "
我认为 spinach 更好比 cucumber http://codegram.github.com/spinach Test::Unit for functional and unit tests, and spinach for integration tests.
我一开始写测试是用 Test::Unit,遇到问题到 google 去搜找到大部分都是 RSpec,后来转用了 RSpec,把项目之前的 Test::Unit 用 RSpec 重写了,后来配合 cucumber 和 capybara 后进行 BDD 开发,觉得在写测试的代码的过程就是在设计,能把流程理清,等测试写好了再去实现的时候就很清晰要怎么去做。我 Test::Unit 用得不深入可能没体会到他的好处,在国外的社区也经常有存在这方面的争论,DHH 就坚持用 Test::Unit(毕竟是他写的 XD)。
虽然我也不喜欢 cucumber。 但是我不喜欢他的原因是他做 integration test 的方式和直接写 capybara with rspec 方式没啥本质的区别,还变复杂了... 所以我更倾向 capybara with rspec....
即使就是用 cucumber 写,我觉得程序员写 scenario 和 QA 写还是不一样的... 前者的目的通常是做 integration test 通常 driver 是用 rack_test ... 而后者的目的通常是为了验收或者是自动化测试.. 通常 driver 用 selenium 我觉得很不一样...只不过碰巧用了一个工具而已...
关于 minitest or rspec
rspec... +1
其实 both ok... 投一票完全是个人偏好...
通常按惯例第一个人提啥,后面就跟着用了...
我不能理解为什么有人提了 一种测试,另一个人会提其他的.... 除非他有明显的个人偏好...就算如此 也应该做出说明并一并改写以前所有的测试....
如果争论不出结果...就用我说那个不是惯例的惯例吧.... :p
竟然百度搜出三年前的帖子。那时候写测试用的是 nunit (.NET), 但转到 ruby 就一直用 rspec。也曾经和同事为了 rspec 还是 Test::Unit‘争执’。最后。。还是因为项目已经 rspec,所以继续 rspec 吧。