单元测试Chef提供者

use*_*286 5 unit-testing chef-infra chefspec

如何为Chef提供商编写单元测试?

到目前为止,我们的单元测试策略使用ChefSpec作为配方,我们为库中的提供程序填充了大部分有趣的逻辑,使逻辑更易于测试.但是,我们仍遇到供应商调用其他资源(以及其他简单的逻辑问题)的问题.例如:

action :run do

   helper = Helper.new
   template '/etc/hosts' do
     source 'hosts.erb'
     variables ({
              "host" => @new_resource.host,
              "ip_address" => node['ipaddress']
          })
     only_if { helper.update_hosts }
   end

   service 'httpd' do
      action :restart
   end
end
Run Code Online (Sandbox Code Playgroud)

(这不是真正的代码,只是一个简单的例子)

我们要做的是单独测试此提供程序以检查逻辑错误.ChefSpec有能力进入LWRP,但看起来这会迫使我们将LWRP放入配方中,而我们的许多烹饪书基本上都是LWRP库而没有配方.我们还想在我们的测试中保持一个干净的分离,所以通过查看文件名很明显哪个组件失败了.

另外,如果LWRP定义中存在任何语法错误,测试会自动失败,那将是很好的.例如:

action :run do
   template '/etc/hosts/' do
     source_whoops 'hosts.erb'
     action :whoops
   end
end
Run Code Online (Sandbox Code Playgroud)

如果由于属性名称定义不正确而导致测试失败,并且操作名称不存在(就像ChefSpec一样),那将是非常好的.

我提出的唯一解决方案是基本上创建一个"测试食谱" - 一个单独的食谱,用一个食谱定义每个LWRP 1:1,所以ChefSpec可以这样进入它.这似乎是一个合理但不太理想的解决方案.

use*_*286 6

看起来有一个(最近的)解决方案.

首先,这个拉取请求基本上会按照我的要求进行,尽管ChefSpec维护者已经拒绝了这个请求是出于可以理解的原因.

维护者建议使用mycookbook_test模式 - 单独的食谱保留所有单元测试.这将允许一个简单的1 recipe-per-lwrp方法.

此外,这种方法使烹饪书不受任何单元测试的影响,这对于食谱的消费者来说是很好的.消费者可能想要运行他们自己的单元测试,并且不需要(或希望)在第三方烹饪书上运行测试.