2013-03-05 16 views
6

Tôi khá mới đối với Ruby, nhưng tôi đã làm rất nhiều nghiên cứu về thử nghiệm Chef trong hai tuần qua. Bài kiểm tra này sử dụng ChefSpec & Fauxhai, nhưng nó không trông rất "ruby-ish" và tôi đã hy vọng cộng đồng có thể cho tôi một số gợi ý về phong cách mã hóa. Có cách nào tốt hơn để viết một vòng lặp lồng nhau như thế này?Phản hồi về kiểu mã hóa Ruby/ChefSpec

sách dạy nấu ăn/foo/công thức nấu ăn/default.rb

package "foo" do 
    action :install 
end 

sách dạy nấu ăn/foo/spec/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 

Bất kỳ và tất cả các thông tin phản hồi được chào đón. Cảm ơn bạn!

+2

https://github.com/bbatsov/ruby-style-guide là tài nguyên chung cho các nguyên tắc mã hóa Ruby được đề xuất. Tôi không nghĩ rằng bạn có thể làm nhiều việc để làm sạch những vòng lặp lồng nhau đó trong khi vẫn duy trì khả năng đọc. –

+0

Tôi đã đọc qua hướng dẫn nhưng tôi không thấy nhiều tôi có thể cải thiện. Cảm ơn vì bạn đã phản hồi! – Rapsey

Trả lời

6

Trước tiên, thực tiễn phổ biến là trích xuất ChefRunner instantiation thành let helper. Bạn cũng có thể bao gồm tất cả các cấu hình Fauxhai có:

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 

Cú pháp expect có vẻ là recommended qua should. Nhưng trong ví dụ này, tôi sẽ sử dụng một lớp lót:

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

Để làm sạch vòng lặp một chút, bạn có thể sử dụng RSpec's shared examples. Ví dụ mở rộng hơn một chút:

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

Một cách khác có thể là sử dụng các thẻ RSpec ('mô tả 'foo', nền tảng: [...] do ...') và lặp lại các ví dụ được chia sẻ dựa trên đó. –