zoukankan      html  css  js  c++  java
  • Ruby元编程:动态添加类属性及其实际应用

    上个星期测试道的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添加属性。代码如下:

     1 require 'yaml'
     2 
     3 module ConfigParser
     4   class << self
     5     def add_attribute(klass, symbol)
     6       codes = %Q{
     7         def #{symbol}
     8           return @#{symbol}
     9         end
    10         
    11         def #{symbol}=(value)
    12           @#{symbol} = value
    13         end
    14       }
    15 
    16       klass.instance_eval(codes)
    17     end
    18 
    19     def expand_configs(configs = {})
    20       configs.each do |key, value|
    21         expand_sub_configs(key, value)
    22       end  
    23     end
    24     
    25     def expand_sub_configs(prefix, configs)
    26       if configs.class != Hash
    27         add_attribute(Configs, prefix)
    28         eval("Configs.#{prefix} = configs")
    29       else
    30         configs.each do |key, value|
    31           expand_sub_configs(prefix + '_' + key, value)
    32         end
    33       end
    34     end
    35   end 
    36 end
    37 
    38 if ARGV.size != 1
    39   puts "Usage: ..."
    40   exit(-1)
    41 end
    42 
    43 Configs = Class.new
    44 
    45 ConfigParser.expand_configs(YAML.load(File.open(ARGV[0])))
    46 
    47 puts 'Storage information:'
    48 puts " #{Configs.Storage_IP}"
    49 puts "  #{Configs.Storage_Port}"
    50 puts "  #{Configs.Storage_SSL_Port}"
    51 puts "  #{Configs.Storage_Service_Port}
    "
    52 
    53 puts 'DB information: '
    54 puts "  #{Configs.DB_IP}"
    55 puts "  #{Configs.DB_User}"
    56 puts "  #{Configs.DB_Password}
    "
    57 
    58 puts 'Manifests information: '
    59 Configs.Manifests.each do |info|
    60   info.each do |k, v|
    61     puts "  #{k}: #{v}"
    62   end
    63 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
  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/panda_lin/p/3373754.html
Copyright © 2011-2022 走看看