通常自动化测试项目到了一定的程序,编写的测试代码自然就会很多,如果很早已经编写的测试脚本现在某些基础函数、业务函数需要修改,那么势必要找出那些引用过这个被修改函数的地方,有些IDE支持全文查找和引用查找,而有些简单的可能就没有,因为日后要用到统计功能、和一些其它的需求,所以写了一个脚本。除了跟目录下全文查找引用过的文件外,还是支持统计查找到的数量,一次可以查找多个关键字,支持按主关键字来归类。

#encoding: utf-8 
import os 
import sys 
import re 
 
reload(sys) 
sys.setdefaultencoding(\"utf-8\") 
 
short_exclude = [\".svn\", \"sendbox\"]  ##不检查的文件、目录名 
long_exclude = []  ##不包含检查的文件、目录的完整路径 
extend_name = [\".rb\"] ##指定检查的文件后缀 
temp_key_words = [  
  { 
    \"key\" : \"#作者:\", 
    \"display\" : \"作者\", 
    \"times\" : -1, 
    \"match\" : \"include\", 
    \"primary_key\" : True, 
  }, 
  { 
    \"key\" : \"#[summary]\", 
    \"display\" : \"完成用例数\", 
    \"times\" : -1, 
    \"match\" : \"include\", 
  },   
  { 
    \"key\" : \"File.expand_path\", 
    \"display\" : \"有状态行数\", 
    \"times\" : -1, 
    \"ignore_case\" : True, 
  },   
  { 
    \"key\" : \"def\\s+test_\", 
    \"display\" : \"有效用例数\", 
    \"times\" : -1, 
    \"match\" : \"regex\", 
    \"ignore_case\" : True, 
  },   
  { 
    \"key\" : \"#def\\s+test_\", 
    \"display\" : \"注释用例数\", 
    \"times\" : -1, 
    \"match\" : \"regex\", 
    \"ignore_case\" : True, 
  },   
] 
 
for kv in temp_key_words: 
  if not \"key\" in kv: 
    raise \"以下的列表中没有【key】值!\\n%s\" % kv 
  if not \"key\" in kv: 
    raise \"以下的列表中没有【display】值!\\n%s\" % kv   
  kv[\'times\'] = kv.get(\'times\', -1)  ##默认为不限制检查次数    
  if kv.get(\"ignore_case\", True)==False: ##默认忽略大小写 
    flag = 0 
  else: 
    flag = re.I     
  kv[\'pattern\'] = re.compile(kv[\'key\'], flag) 
  if kv.get(\"primary_key\", False): 
    kv[\'times\'] = 1 
import copy 
key_words = []     
 
def deepcopy(objs): 
  t_list = [] 
  for obj in objs: 
    t_list.append(copy.copy(obj)) 
  return t_list 
 
def loop_case(root_dir): 
  t_sum = [] 
  print root_dir 
  sub_gen = os.listdir(root_dir) 
  for sub in sub_gen: 
    if sub in short_exclude: ##在不检查文件、目录范围中 
      continue 
    abs_path = os.path.join(root_dir, sub) 
    if long_exclude: 
      is_exclude = False 
      for exclude in long_exclude: 
        if exclude == abs_path[-len(exclude):]: 
          is_exclude = True 
          break 
      if is_exclude: 
        continue 
    print abs_path 
    if os.path.isdir(abs_path): 
      print \"dir\" 
      t_sum.extend(loop_case(abs_path)) 
    elif os.path.isfile(abs_path):       
      if not \".\" + abs_path.rsplit(\".\", 1)[1] in extend_name: ##不在后缀名 检查范围中 
        continue 
      print \"file\" 
      global key_words  
      key_words = deepcopy(temp_key_words)      
      t_sum.append(count_case(abs_path))  
  return t_sum     
   
def count_case(abs_path):   
  t_dict = {} 
  with open(abs_path) as f: 
    for l in f: 
      l = l.strip() 
      match_rule(l)  
  index = 0 
  count_result = [0] * len(key_words)    
  for kv in key_words:  
    if \'primary_key\' in kv: 
      t_dict[\'primary_key\'] = kv.get(\'display\') 
      t_dict[\'primary_key_value\'] = kv.get(\'primary_key_value\', \"None\") 
    count_result[index] = -1-kv[\'times\']  
    index += 1  
  t_dict[\'match_result\'] = count_result 
  t_dict[\'file_path\'] = abs_path  
  return t_dict 
 
def match_rule(line): 
  primary_key = None  
  for kv in key_words: 
    match = False          
    if kv[\'times\']==0: ##检查次数已满,不再检查 
      continue 
    if kv.get(\'match\', \"\") == \"regex\": ##指定了匹配方式为:正则 
      if kv[\'pattern\'].match(line):  ##匹配正则成功 
        match = True 
    else:  ##默认匹配方式为: 包含 
      if kv[\'key\'] in line:  ##包含了指定字符串 
        match = True 
    if match: 
      if kv.get(\'primary_key\', False): 
        kv[\'primary_key_value\'] = line.split(kv[\'key\'])[1].strip()   
#        kv[\'primary_key\'] = False       
      kv[\'times\'] -= 1      ##匹配成功,同理剩余匹配的次数 -1 
  return primary_key     
   
def format_info(sum_list): 
  tip_list = []   
  p_k_dict = {} 
  for d in sum_list: 
    p_k = d[\'primary_key_value\'] 
    if p_k not in p_k_dict: 
      p_k_dict[p_k] = [0] * len(key_words)  
    temp_list = [] 
    m = d[\'match_result\'] 
    temp_list.append(\"文件名称:%s\\n%s:%s\\n\" % (d[\'file_path\'], d[\'primary_key\'], d[\'primary_key_value\'])) 
    for i in range(len(m)): 
      if \'primary_key\' in key_words[i]:         
        continue  
      else: 
        t_s = str(m[i]) 
      temp_list.append(\"%s:%s\\n\" % (key_words[i][\"display\"], t_s)) 
      p_k_dict[p_k][i] += m[i] 
    tip_list.append(\"\".join(temp_list)) 
    p_k_dict[p_k][0] += 1 
  tip_list.append(\"===========================主键统计分割线===============================\") 
  total_dict = {} 
  for kv in key_words: 
    if \'primary_key\' not in kv: 
      total_dict[kv[\'display\']] = 0 
  total_dict[\'全部文件数\'] = 0 
  for k,v in p_k_dict.items(): 
    temp_list = [] 
    temp_list.append(\"主键:%s\\n文件总数:%s\\n\" % (k, v[0])) 
    for i in range(1, len(v)): 
      temp_list.append(\"%s:%s\\n\" % (key_words[i][\"display\"], str(v[i])))  
      total_dict[key_words[i][\"display\"]] += v[i]     
    tip_list.append(\"\".join(temp_list)) 
    total_dict[\'全部文件数\'] += v[0] 
  tip_list.append(\"===========================全部统计分割线===============================\") 
  temp_list = [] 
  for k,v in total_dict.items(): 
    temp_list.append(\"全部%s:%s\\n\" % (k,v)) 
  tip_list.append(\"\".join(temp_list)) 
  tip_msg = \"\\n\".join(tip_list) 
  print tip_msg 
  open(r\"sum_case.log\", \"w\").write(tip_msg) 
   
if __name__==\"__main__\": 
  if len(sys.argv) > 1: 
    root_list = sys.argv[1:] 
  else: 
    root_list = [os.curdir] 
  sum_list = [] 
  for root_dir in root_list:   
    if os.path.exists(root_dir) and os.path.isdir(root_dir): 
      sum_list.extend(loop_case(root_dir)) 
      format_info(sum_list) 
    else: 
      print \"给定的根目录无效\\n%s\" % root_dir 

可以通过配置开头的设置来确定检查什么关键字,文件类型,过滤哪些文件和目录等