2013-03-05 43 views
6

我对Ruby很新,但过去两周我一直在做大量的厨师测试研究。这个测试使用了Fauxhai的ChefSpec &,但它看起来并不是很“红宝石”,我希望社区能够给我一些关于编码风格的指导。有没有更好的方式来编写这样的嵌套循环?关于Ruby/ChefSpec编码风格的反馈

食谱/富/食谱/ default.rb

package "foo" do 
    action :install 
end 

食谱/富/规格/ default_spec.rb

require 'chefspec' 

describe 'foo::default' do 
    platforms = { 
    "debian" => ['6.0.5'], 
    "ubuntu" => ['12.04', '10.04'], 
    "centos" => ['5.8', '6.0', '6.3'], 
    "redhat" => ['5.8', '6.3'], 
    "mac_os_x" => ['10.6.8', '10.7.4', '10.8.2'], 
    "windows" => ['2008R2'] 
    } 

    platforms.each do |platform,versions| 
    versions.each do |version| 
     context "on #{platform} #{version}" do 
     before do 
      Fauxhai.mock(platform: platform, version: version) 
     end 

     it 'should install foo' do 
      @runner = ChefSpec::ChefRunner.new.converge('foo::default') 
      @runner.should install_package 'foo' 
     end 
     end 
    end 
    end 
end 

任何和所有的反馈是值得欢迎的。谢谢!

+2

https://github.com/bbatsov/ruby-style-guide是建议的Ruby编码指南的一个很好的一般资源。我认为在保持可读性的同时清理这些嵌套循环并不是很多。 – 2013-03-05 13:58:42

+0

我已阅读指南,但我看不出有太多的改进。感谢您的反馈! – Rapsey 2013-03-06 08:53:00

回答

6

首先,通常的做法是将ChefRunner实例化为let助手。您也可以包括所有Fauxhai配置有:

let(:chef_run) do 
    ChefSpec::ChefRunner.new(platform: platform, version: version) do |node| 
    node.set['foo']['bar'] = 'baz' 
    # .... 
    end.converge('foo::default') 
end 

it "installs foo" do 
    expect(chef_run).to install_package 'foo' 
end 

expect语法似乎是recommended超过should。但是,在这个例子中我会用一个班轮:

subject do 
    ChefSpec::ChefRunner.new(platform: platform, version: version).converge('foo::default') 
end 
it { should install_package 'foo' } 

要清理的循环一点,你可以使用RSpec's shared examples。稍微扩展一些例子:

require 'chefspec' 

shared_examples 'foo' do |platform, version| 
    context "on #{platform} #{version}" do 
    let(:users) { %w[user1 user2] } 
    let(:chef_run) do 
     ChefSpec::ChefRunner.new(platform: platform, version: version) do |node| 
     node.set['foo']['users'] = users 
     end.converge('foo::default') 
    end 
    subject { chef_run } 

    it { should install_package 'foo' } 

    it "creates specified users" do 
     users.each { |u| expect(chef_run).to create_user u } 
    end 
    end 
end 

describe 'foo::default' do 
    platforms = { 
    'debian' => ['6.0.5'], 
    'ubuntu' => ['12.04', '10.04'], 
    'centos' => ['5.8', '6.0', '6.3'], 
    'redhat' => ['5.8', '6.3'], 
    'mac_os_x' => ['10.6.8', '10.7.4', '10.8.2'], 
    'windows' => ['2008R2'] 
    } 

    platforms.each do |platform, versions| 
    versions.each do |version| 
     include_examples 'foo', platform, version 
    end 
    end 
end 
+0

另一种方式可能是使用RSpec标签('describe'foo',平台:[...] ...),并基于此循环共享示例。 – 2013-12-20 22:13:17