首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用RSpec和PDK测试内部类

用RSpec和PDK测试内部类
EN

Stack Overflow用户
提问于 2020-01-20 09:45:07
回答 1查看 424关注 0票数 1

对于运行tomcat的webservice,我有一个相当基本的木偶模块。我想要在Tomcat的catalina.out文件上设置日志旋转,我想从编写一个测试开始,该测试确认模块中包含日志旋转,并设置了正确的设置。

下面是我的webservice.pp的简化版本,例如:

代码语言:javascript
复制
class my_module::webservice (
  ...
){
  include ::tomcat_server

  ...

  logrotate::rule { 'tomcat':
    path          => '/var/log/tomcat/catalina.out',
    rotate        => 1,
    rotate_every  => 'day',
    copytruncate  => true,
    missingok     => true,
    compress      => true,
    delaycompress => true,
  }
}

我在我的.fixtures.yml中包括了日志旋转锻造模块如下:

代码语言:javascript
复制
fixtures:
  forge_modules:
    logrotate:
      repo: 'puppet-logrotate'
      ref:  '3.2.1'
    ...

但是,我只能编写一个测试,以确认模块中包含了logrotate,如下所示:

代码语言:javascript
复制
require 'spec_helper'

describe 'my_module::webservice' do
  on_supported_os.each do |os, os_facts|
    context "on #{os}" do
      let(:facts) { os_facts }

      it { is_expected.to compile }

      it { is_expected.to contain_class('logrotate') }
    end
  end
end

这是不起作用的(如果我从init.pp中删除log转速块,那么测试仍然会通过):

代码语言:javascript
复制
it { is_expected.to contain_class('logrotate::conf') }

也不要求with

代码语言:javascript
复制
it { is_expected.to contain_class('logrotate') \
  .with('path'          => '/var/log/tomcat/catalina.out',
        'rotate'        => 1,
        'rotate_every'  => 'day',
        'copytruncate'  => true,
        'missingok'     => true,
        'compress'      => true,
        'delaycompress' => true,
  )
}

另外,单独/嵌套的describe块也不会:

代码语言:javascript
复制
describe 'logrotate::rule' do
  let(:title) { 'tomcat' }
  let(:params) do
    {
        'path'          => '/var/log/tomcat/catalina.out',
        'rotate'        => 1,
        'rotate_every'  => 'day',
        'copytruncate'  => true,
        'missingok'     => true,
        'compress'      => true,
        'delaycompress' => true,
    }
  end
end

在rspec文档中,除了定义测试类之外,我找不到任何提及其他内容的内容。我能做我想做的事吗?

这是我的目录布局:

代码语言:javascript
复制
puppet
  `- modules
        `- my_module
             |- data
             |- manifests
             |    |- init.pp
             |    `- webservice.pp
             |- spec
             |    |- classes
             |    |    `- webservice_spec.rb
             |    `- spec_helper.rb
             |- .fixtures.yml
             |- Gemfile
             |- hiera.yaml
             |- metadata.json
             `- Rakefile
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-20 17:28:39

对于运行tomcat的webservice,我有一个相当基本的木偶模块。我想要在Tomcat的catalina.out文件上设置日志旋转,我想从编写一个测试开始,该测试确认模块中包含日志旋转,并设置了正确的设置。

听起来很合理。但是这个..。

下面是我的init.pp的简化版本,例如: 类my_module::webservice (. ){

..。最好的做法是。如果它存在,那么模块my_modulemy_module清单应该只定义类my_module。名为my_module::webservice的类应该在模块my_module中名为webservice.pp的清单中定义。对模块布局的期望是木偶在线文档中的记录在案。尽管您可能能够克服这些规范中的某些差异,但这样做只会有缺点。

在这一点上,我观察到“内部类”不是惯用的木偶术语,它暗示着对您正在使用的内容的误解。特别是这个..。

日志旋转::规则{ 'tomcat': ..。

..。根本不声明一个类,而是声明一个类型为logrotate::rule的资源,该资源显然是由木偶/日志旋转模块提供的一个定义类型。通常,声明资源并不意味着来自提供资源类型的模块(如果有的话)中的类的任何内容。

此外,尽管声明logrotate::rule资源完全有可能导致类logrotate也包含在目录中,但这将是logrotate::rule的实现细节,因此您的规范测试不应该对其进行测试。只有当my_module::webservice本身声明类logrotate时,它的测试才会对其进行检查。

你接着说:

这是不起作用的(如果我从init.pp中删除log转速块,那么测试仍然会通过): 它{ is_expected.to contain_class(‘log转速::conf’)}

您还没有给我们提供足够的代码来确定当测试包含在其中时,测试为什么会通过,但是如果满足了这种期望,那么有些事情是非常奇怪的。logrotate::conf也是一个定义的(资源)类型,而不是一个类,因此期望永远不会成功。按照我前面介绍的主题,如果类my_module::webservice没有直接声明任何logrotate::conf资源,那么它的测试就不应该检查其中的资源。

也不要求: 它{ is_expected.to contain_class('logrotate') \ .with('path‘=> '/var/log/tomcat/catalina.out’、‘=> 1’、'rotate_every‘=> 'day’、‘复制’=> true、'missingok‘=> true、'compress’=> true、'delaycompress‘=> true,’delaycompress‘=> true,’delaycompress‘=> true,]}}

当然不会成功。它表示了类logrotate声明的期望,但实际上声明的是logrotate::rule类型的资源。即使logrotate::rule声明了logrotate,人们也不会期望它传递自己的参数列表。

此外,也没有单独/嵌套的描述块: 描述“日志旋转::规则”做 ..。

再说一次,这并不奇怪。这样一个describe块告诉RSpec,logrotate::rule是被测试的类。它不仅不是被测试的类(当然是my_module::webservice),而且,同样,logrotate::rule根本不是一个类。RSpec当然也可以测试定义的类型,但这不是您想要的。

要测试资源是否由测试contain_type(title),下的类声明,可以使用表单的谓词,其中类型名称中的任何命名空间分隔符(::)都被双下划线替换。例如:

代码语言:javascript
复制
it do
  is_expected.to contain_logrotate__rule('tomcat')
end

允许(但可选)包含一个或多个with子句,以指定指定资源的声明参数的期望。按照你看起来一直想做的事情,也许这会更充分地表达你想要做的事情:

代码语言:javascript
复制
require 'spec_helper'

describe 'my_module::webservice' do
  on_supported_os.each do |os, os_facts|
    context "on #{os}" do
      let(:facts) { os_facts }

      it do
        is_expected.to compile
        is_expected.to contain_logrotate__rule('tomcat')
          .with(
            path: '/var/log/tomcat/catalina.out',
            rotate: 1,
            rotate_every: 'day',
            copytruncate: true,
            missingok: true,
            compress: true,
            delaycompress: true
          )
      end
    end
  end
end

顺便指出,当您想要针对同一个示例测试多个谓词时,将它们组合在同一个it块中比将每个谓词放在自己的it块中要有效得多。如前所述,您可能会注意到测试运行时间的差异,即使只是将两个it块组合成一个。

此外,上面的示例演示了接近避免来自pdk validate的警告所需的编码风格,这就引出了另一个要点:在尝试单元测试之前,验证pdk validate完成时没有错误或警告总是很有用的。您可能会发现,它对Puppet和Ruby代码风格都过于挑剔,但它也会引出一些导致神秘测试失败的问题。而且,它的运行速度要比测试快得多,并且它将基本上收集Puppet和Ruby代码中的所有语法错误。令人沮丧的是,您的测试需要很长时间才能因为一个小语法错误而失败。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59820569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档