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
  • 相关阅读:
    iview表单验证 只能输入小数或者整数
    iView之Modal(一级弹窗和二级弹窗)
    Vue+iView 引入iconfont
    iView爬坑记——表单验证
    有关使用 iview 表单验证的问题
    数据结构
    数学
    Zookeeper
    maven 打包
    区块链
  • 原文地址:https://www.cnblogs.com/panda_lin/p/3373754.html
Copyright © 2011-2022 走看看