“远程运行Serverspec测试时,未定义的方法`[]'为nil:NilClass”错误

时间:2016-06-20 11:04:40

标签: ruby vagrant rake serverspec

我使用inifile gem进行了Serverspec测试:

require 'spec_helper'
require 'inifile'

describe 'inifile test -' do
  file = '/tmp/testfile1.ini'
  file_ini = IniFile.load(file)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end

如果在机器上本地执行rake,则测试通过(在安装了inifile gem的Ubuntu guest虚拟机或OS X主机上执行)。

但是,当我针对Vagrant框运行rake时(即在使用SSH连接到Vagrant上的Ubuntu的主机上),它会失败并显示以下消息:

1) inifile test - testfile1.ini should contain expected values
   On host `molecule-test'
   Failure/Error: expect(file_ini['section1']['variable1']).to eq('value1')
   NoMethodError:
     undefined method `[]' for nil:NilClass

   # ./spec/inifile_spec.rb:8:in `block (2 levels) in <top (required)>'

我使用Serverspec的默认Rakefilespec_helper.rb

/tmp/testfile1.ini如下所示,尽管测试失败,无论内容如何:

[section1]
variable1=value1

在我看来,某些问题与未转义的角色有关,但我不太确定。

有什么不对?

2 个答案:

答案 0 :(得分:1)

确保在Vagrant实例上安装了inifile之后,这样做的方式就是这样:

describe 'inifile test -' do
  file_ini = command("ruby -rinifile -e \"print IniFile.load('/tmp/testfile1.ini')['section1']['variable1']\"").stdout
  it 'testfile1.ini should contain expected values' do
    expect(file_ini).to eq('value1')
  end
end

我不知道file变量范围是否适用于command方法,因此我可以安全地使用它。

Asker techraf在充分了解inifile API的情况下添加了这条更清晰的路线。

describe 'inifile test -' do
  file_ini = IniFile.new(content: command("cat /tmp/testfile1.ini").stdout)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end

通过一些合作,我们得出了这个有希望的最佳解决方案。

describe 'inifile test -' do
  file_ini = IniFile.new(content: file('/tmp/testfile1.ini').content)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end

答案 1 :(得分:0)

NoMethodError:
     undefined method `[]' for nil:NilClass

上述错误可能表示:ssh后端没有正确配置,具有必需的属性(可能缺少目标主机)

通过设置以下属性来配置:ssh后端:

set :backend, :ssh
set :host,       ENV['TARGET_HOST']

在上面的代码片段中,要连接的主机使用环境变量传入(可能使用Rake配置)

如果您需要对ssh连接进行更精细的控制,例如使用SSH密钥或ProxyCommand,您需要添加set :ssh_options, options

实施例:     要求&#39; net / ssh&#39;

# ...

host = ENV['TARGET_HOST']

#Configure SSH options
options = Net::SSH::Config.for(host)
options[:user] = ENV['USER']
options[:port] = 22
options[:keys] = ENV['TARGET_PRIVATE_KEY']

# Configure serverspec with the target host and SSH options
set :host,        host
set :ssh_options, options