您的位置:首页 > 编程语言 > Ruby

Ruby元编程:动态添加类属性及其实际应用

2013-10-17 11:26 351 查看
上个星期测试道的Monkey老师和我聊到测试用例参数过多的问题,其实这样的问题在我这里也同样经历过。比如我的测试用例必须面对不同的测试环境,每个环境有无数的参数,开发的最初阶段,因为参数少,所以就放在执行的命令行里,随着测试用例的不断增长,参数从4-5个增长到30多个,而且每个用例使用的参数也不完全相同,有使用ABCD的,有使用ADHJ的。另外有些参数想传一个数组进去,用命令行参数的方法就很难处理。

经过考虑,果断的使用配置文件来解决问题。选择配置文件当时有两个方案,一个是直接写成Ruby代码,但是考虑到要和自动化测试框架共享配置文件,所以最后决定使用YAML格式。Ruby对YAML的支持非常好,你可以用如下方式访问某个配置参数Configs['Host']['IP'],考虑到让我们的测试代码更直观,我们希望能用Configs.Host_IP的方式访问环境参数。

YAML配置文件例子:

Storage:
IP: 192.168.1.1
Port: 80
SSL_Port: 443
Service_Port: 2000

DB:
IP: 192.168.1.2
User: Tom
Password: test

Manifests:
- IP: 192.168.2.1
- IP: 192.168.2.2
- IP: 192.168.2.3
- IP: 192.168.2.4


我们希望能用Configs.Storage_IP,Configs.DB_Password这样的方法拿到参数,对于Manifests,我们的输入是数组,则希望能用Configs.Manifests[i]['IP']的方式访问。利用Ruby的元编程特性,在我们读取YAML文件解析生成数组后,我们就可以遍历每个元素然后动态为Configs添加属性。代码如下:

require 'yaml'

module ConfigParser
class << self
def add_attribute(klass, symbol)
codes = %Q{
def #{symbol}
return @#{symbol}
end

def #{symbol}=(value)
@#{symbol} = value
end
}

klass.instance_eval(codes)
end

def expand_configs(configs = {})
configs.each do |key, value|
expand_sub_configs(key, value)
end
end

def expand_sub_configs(prefix, configs)
if configs.class != Hash
add_attribute(Configs, prefix)
eval("Configs.#{prefix} = configs")
else
configs.each do |key, value|
expand_sub_configs(prefix + '_' + key, value)
end
end
end
end
end

if ARGV.size != 1
puts "Usage: ..."
exit(-1)
end

Configs = Class.new

ConfigParser.expand_configs(YAML.load(File.open(ARGV[0])))

puts 'Storage information:'
puts " #{Configs.Storage_IP}"
puts "  #{Configs.Storage_Port}"
puts "  #{Configs.Storage_SSL_Port}"
puts "  #{Configs.Storage_Service_Port}\n"

puts 'DB information: '
puts "  #{Configs.DB_IP}"
puts "  #{Configs.DB_User}"
puts "  #{Configs.DB_Password}\n"

puts 'Manifests information: '
Configs.Manifests.each do |info|
info.each do |k, v|
puts "  #{k}: #{v}"
end
end


执行命令ruby test.rb config.yml得到输出如下:

Storage information:
192.168.1.1
80
443
2000
DB information:
192.168.1.2
Tom
test
Manifests information:
IP: 192.168.2.1
IP: 192.168.2.2
IP: 192.168.2.3
IP: 192.168.2.4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: