免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3514 | 回复: 1
打印 上一主题 下一主题

Ruby 1.9 Rspec 风格 Unit Test MiniTest::Spec介绍 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-20 15:48 |只看该作者 |倒序浏览
Ruby 1.9 Rspec 风格 Unit Test MiniTest::Spec介绍








MiniTest是1.9后加到ruby标准库里的。其中,有几个部分当在1.9中写

Ruby代码
  1. 1.require 'test/unit'  
复制代码
require 'test/unit'时,会兼容的把MiniTest:Unit载入,然而MiniTest::Unit只是增加了assertions

比较显著的部分是MiniTest::Spec和MiniTest::Mock,夜猪对此比较感冒,当然效果是比不了Rspec啦,比如before do还是不能支持before :all do这样的回调。对于ruby标准库来说还是不错的开始。简介如下:

例如之前的unittest可能会这么写

Ruby代码
  1. 1.require 'test/unit'  
  2. 2.  
  3. 3.class TestArray < Test::Unit::TestCase   
  4. 4.  def test_array_can_be_created_with_no_arguments   
  5. 5.    assert_instance_of Array, Array.new  
  6. 6.  end  
  7. 7.  
  8. 8.  def test_array_of_specific_length_can_be_created   
  9. 9.    assert_equal 10, Array.new(10).size   
  10. 10.  end  
  11. 11.end  
  12. require 'test/unit'

  13. class TestArray < Test::Unit::TestCase
  14.   def test_array_can_be_created_with_no_arguments
  15.     assert_instance_of Array, Array.new
  16.   end

  17.   def test_array_of_specific_length_can_be_created
  18.     assert_equal 10, Array.new(10).size
  19.   end
  20. end
复制代码
之后,可以这样写

Ruby代码
  1. 1.require 'minitest/spec'  
  2. 2.require 'minitest/autorun'  
  3. 3.  
  4. 4.describe Array do  
  5. 5.  it "can be created with no arguments" do  
  6. 6.    Array.new.must_be_instance_of Array  
  7. 7.  end  
  8. 8.  
  9. 9.  it "can be created with a specific size" do  
  10. 10.    Array.new(10).size.must_equal 10   
  11. 11.  end  
  12. 12.end  
  13. require 'minitest/spec'
  14. require 'minitest/autorun'

  15. describe Array do
  16.   it "can be created with no arguments" do
  17.     Array.new.must_be_instance_of Array
  18.   end

  19.   it "can be created with a specific size" do
  20.     Array.new(10).size.must_equal 10
  21.   end
  22. end
复制代码
再来一个之前的setup和teardown


Ruby代码
  1. 1.require 'minitest/autorun'  
  2. 2.  
  3. 3.class TestMeme < MiniTest::Unit::TestCase   
  4. 4.  def setup   
  5. 5.    @meme = Meme.new  
  6. 6.  end  
  7. 7.  
  8. 8.  def test_that_kitty_can_eat   
  9. 9.    assert_equal "OHAI!", @meme.i_can_has_cheezburger?   
  10. 10.  end  
  11. 11.  
  12. 12.  def test_that_it_will_not_blend   
  13. 13.    refute_match /^no/i, @meme.will_it_blend?   
  14. 14.  end  
  15. 15.end  
  16.   require 'minitest/autorun'

  17.   class TestMeme < MiniTest::Unit::TestCase
  18.     def setup
  19.       @meme = Meme.new
  20.     end

  21.     def test_that_kitty_can_eat
  22.       assert_equal "OHAI!", @meme.i_can_has_cheezburger?
  23.     end

  24.     def test_that_it_will_not_blend
  25.       refute_match /^no/i, @meme.will_it_blend?
  26.     end
  27.   end
复制代码
变成如下:


Ruby代码
  1. 1.  require 'minitest/autorun'  
  2. 2.  
  3. 3.  describe Meme do  
  4. 4.    before do  
  5. 5.      @meme = Meme.new  
  6. 6.    end  
  7. 7.  
  8. 8.    describe "when asked about cheeseburgers" do  
  9. 9.      it "must respond positively" do  
  10. 10.        @meme.i_can_has_cheezburger?.must_equal "OHAI!"  
  11. 11.      end  
  12. 12.    end  
  13. 13.  
  14. 14.    describe "when asked about blending possibilities" do  
  15. 15.      it "won't say no" do  
  16. 16.        @meme.will_it_blend?.wont_match /^no/i   
  17. 17.      end  
  18. 18.    end  
  19. 19.  end  
  20. 20.#这里是我说的那个,还是不支持所有测试before :all  
  21.   require 'minitest/autorun'

  22.   describe Meme do
  23.     before do
  24.       @meme = Meme.new
  25.     end

  26.     describe "when asked about cheeseburgers" do
  27.       it "must respond positively" do
  28.         @meme.i_can_has_cheezburger?.must_equal "OHAI!"
  29.       end
  30.     end

  31.     describe "when asked about blending possibilities" do
  32.       it "won't say no" do
  33.         @meme.will_it_blend?.wont_match /^no/i
  34.       end
  35.     end
  36.   end
复制代码
#这里是我说的那个,还是不支持所有测试before :all


下一篇准备说说MiniTest的Mock
这里也支持skip方法就是cucumber里的@wip

值得注意的是,这个minitest/spec的支持只有短短300多行代码,有条件的推荐读。

然后写unit test一定想知道assertions都有啥吧


Ruby代码
  1. 1.obj.must_be(operator, expected) # for example, 10.must_be :< , 11   
  2. 2.obj.must_be_close_to # the equivalent of assert_in_delta   
  3. 3.obj.must_be_empty - Fails unless obj.empty?   
  4. 4.obj.must_be_instance_of(klass) # Fails unless obj.class == klass   
  5. 5.obj.must_be_kind_of(klass) # Fails unless obj is of class klass or klass is one of its superclasses.   
  6. 6.obj.must_be_nil   
  7. 7.obj.must_be_same_as $ tests for true object equality   
  8. 8.lambda {}.must_be_silent   
  9. 9.obj.must_be_within_delta   
  10. 10.obj.must_be_within_epsilon   
  11. 11.obj.must_equal(other) # Does a ==/eql? comparison between two objects.   
  12. 12.obj.must_include(other)   
  13. 13.obj.must_match(regex) # A regular expression match, e.g. "hello".must_match /w+/   
  14. 14.lambda {}.must_output(stdout, [stderr..]) # The block should have certain output on stdout or stderr. Set stdout to nil just to check stderr.   
  15. 15.lambda {}.must_raise(exception)   
  16. 16.obj.must_respond_to(message)   
  17. 17.obj.must_throw(sym)   
  18. 18.wont_be   
  19. 19.wont_be_empty   
  20. 20.wont_be_instance_of   
  21. 21.wont_be_kind_of   
  22. 22.wont_be_nil   
  23. 23.wont_be_same_as   
  24. 24.wont_equal   
  25. 25.wont_include   
  26. 26.wont_match   
  27. 27.wont_respond_to  
  28. obj.must_be(operator, expected) # for example, 10.must_be :< , 11
  29. obj.must_be_close_to # the equivalent of assert_in_delta
  30. obj.must_be_empty - Fails unless obj.empty?
  31. obj.must_be_instance_of(klass) # Fails unless obj.class == klass
  32. obj.must_be_kind_of(klass) # Fails unless obj is of class klass or klass is one of its superclasses.
  33. obj.must_be_nil
  34. obj.must_be_same_as $ tests for true object equality
  35. lambda {}.must_be_silent
  36. obj.must_be_within_delta
  37. obj.must_be_within_epsilon
  38. obj.must_equal(other) # Does a ==/eql? comparison between two objects.
  39. obj.must_include(other)
  40. obj.must_match(regex) # A regular expression match, e.g. "hello".must_match /w+/
  41. lambda {}.must_output(stdout, [stderr..]) # The block should have certain output on stdout or stderr. Set stdout to nil just to check stderr.
  42. lambda {}.must_raise(exception)
  43. obj.must_respond_to(message)
  44. obj.must_throw(sym)
  45. wont_be
  46. wont_be_empty
  47. wont_be_instance_of
  48. wont_be_kind_of
  49. wont_be_nil
  50. wont_be_same_as
  51. wont_equal
  52. wont_include
  53. wont_match
  54. wont_respond_to
复制代码
当然,也比原版的unit test的assertion好读了,对应关系参考


最后,想要rake跑test目录下所有测试,添加如下Rakefile文件


Ruby代码
  1. 1.require 'rake/testtask'  
  2. 2.  
  3. 3.Rake::TestTask.new do |t|   
  4. 4.  t.libs.push "lib"  
  5. 5.  t.test_files = FileList['test/*_test.rb']   
  6. 6.  t.verbose = true  
  7. 7.end  
  8. require 'rake/testtask'

  9. Rake::TestTask.new do |t|
  10.   t.libs.push "lib"
  11.   t.test_files = FileList['test/*_test.rb']
  12.   t.verbose = true
  13. end
复制代码
关于benchmark放最后


Ruby代码
  1. 1.## optionally run benchmarks, good for CI-only work!   
  2. 2.require 'minitest/benchmark' if ENV["BENCH"]   
  3. 3.  
  4. 4.class TestMeme < MiniTest::Unit::TestCase   
  5. 5.  # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]   
  6. 6.  def bench_my_algorithm   
  7. 7.    assert_performance_linear 0.9999 do |n| # n is a range value   
  8. 8.      @obj.my_algorithm(n)   
  9. 9.    end  
  10. 10.  end  
  11. 11.end  
  12.   ## optionally run benchmarks, good for CI-only work!
  13.   require 'minitest/benchmark' if ENV["BENCH"]

  14.   class TestMeme < MiniTest::Unit::TestCase
  15.     # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000]
  16.     def bench_my_algorithm
  17.       assert_performance_linear 0.9999 do |n| # n is a range value
  18.         @obj.my_algorithm(n)
  19.       end
  20.     end
  21.   end
复制代码
Ruby代码
  1. 1.#或者放到spec里   
  2. 2.  describe Meme do  
  3. 3.    if ENV["BENCH"] then  
  4. 4.      bench_performance_linear "my_algorithm", 0.9999 do |n|   
  5. 5.        100.times do  
  6. 6.          @obj.my_algorithm(n)   
  7. 7.        end  
  8. 8.      end  
  9. 9.    end  
  10. 10.  end  
  11. #或者放到spec里
  12.   describe Meme do
  13.     if ENV["BENCH"] then
  14.       bench_performance_linear "my_algorithm", 0.9999 do |n|
  15.         100.times do
  16.           @obj.my_algorithm(n)
  17.         end
  18.       end
  19.     end
  20.   end
复制代码
输出如下:
Ruby代码
  1. 1.TestBlah    100 1000    10000   
  2. 2.bench_my_algorithm   0.006167    0.079279    0.786993   
  3. 3.bench_other_algorithm    0.061679    0.792797    7.869932
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-11-22 19:29 |只看该作者
很酷。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP