Ruby元编程:动态添加类属性及其实际应用
2013-10-17 11:26
351 查看
上个星期测试道的Monkey老师和我聊到测试用例参数过多的问题,其实这样的问题在我这里也同样经历过。比如我的测试用例必须面对不同的测试环境,每个环境有无数的参数,开发的最初阶段,因为参数少,所以就放在执行的命令行里,随着测试用例的不断增长,参数从4-5个增长到30多个,而且每个用例使用的参数也不完全相同,有使用ABCD的,有使用ADHJ的。另外有些参数想传一个数组进去,用命令行参数的方法就很难处理。
经过考虑,果断的使用配置文件来解决问题。选择配置文件当时有两个方案,一个是直接写成Ruby代码,但是考虑到要和自动化测试框架共享配置文件,所以最后决定使用YAML格式。Ruby对YAML的支持非常好,你可以用如下方式访问某个配置参数Configs['Host']['IP'],考虑到让我们的测试代码更直观,我们希望能用Configs.Host_IP的方式访问环境参数。
YAML配置文件例子:
我们希望能用Configs.Storage_IP,Configs.DB_Password这样的方法拿到参数,对于Manifests,我们的输入是数组,则希望能用Configs.Manifests[i]['IP']的方式访问。利用Ruby的元编程特性,在我们读取YAML文件解析生成数组后,我们就可以遍历每个元素然后动态为Configs添加属性。代码如下:
执行命令ruby test.rb config.yml得到输出如下:
经过考虑,果断的使用配置文件来解决问题。选择配置文件当时有两个方案,一个是直接写成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
相关文章推荐
- ios开发runtime学习三:动态添加方法(实际应用少,面试)
- RunTime应用--动态给分类添加属性
- 动态添加一个视图及其布局属性(要掌握)
- Tabcontrol动态添加TabPage(获取或设置当前选项卡及其属性)
- Android 程式开发:(四)使用Intent调用“内置”应用 —— 4.4添加Category属性
- ko knockoutjs动态属性绑定技巧应用
- IOS开发中Category中动态添加属性
- javascript动态添加、修改、删除对象的属性与方法
- 用于创建动态类型,并添加各个 public 属性的定义
- Js脚本:动态添加HTML自定义属性以及处理html元素的自定义属性(兼容Firefox和IE)
- JS动态给对象添加属性和值的实现方法
- c#.net]做tooltip给控件动态添加属性的做法、IExtenderProvider接口的使用
- jQuery动态添加li标签并添加属性和绑定事件方法
- listView分组及其右键菜单的动态添加
- 给IOS对象添加动态属性
- 动态建立弹出式菜单技术及其应用示例
- python语言是动态语言、给类添加属性、方法、静态方法和类方法、__slots__()、python中的生成器、yield的用法
- vue单页应用中动态添加背景图片
- Python 动态添加属性及方法
- python动态添加属性和方法