Python自动化测试中使用正则表达式根据测试用例名称来过滤选择测试用例工具

该Python脚本用于自动化测试,通过正则表达式从指定目录及其子目录中筛选测试用例。它支持根据模块名、服务器名、优先级和特定关键字过滤测试用例,并加载到测试套件中运行。
#!/usr/bin/python
# fileName: runtest
# encoding = utf-8

import os,sys,getopt,re,time
os.popen('yum install -y unittest-xml-reporting')
import unittest,xmlrunner


def add_path():
    if '/opt/mailcontrol/modules/TQPlugin/' not in sys.path:
        sys.path.append('/opt/mailcontrol/modules/TQPlugin/')
    if '/opt/mdmi/modules' not in sys.path:
        sys.path.append('/opt/mdmi/modules')
    print ''


def walk_dir(dir, modules, servers):
    '''
    Traverse all spcified directories along with sub-directories to present matched files and directories.
    '''
    matched_files = []
    matched_dirs = []
    comp = re.compile('^test_.+\.py$')

    for thisdir, subdirs, fileshere in os.walk(dir):
        os.chdir(thisdir)
        for filename in fileshere:
            if filename.endswith('.py'):
                if thisdir not in sys.path:
                    sys.path.insert(0, thisdir)
                if servers:
                    #m_file = re.search('^test_.+\.py$', filename)
                    if comp.search(filename):
                        file = open(filename, 'r')
                        line_note = ''
                        for i in range(20):
                            line = file.readline().strip('\n')
                            line_note = line_note + line
                        note_obj = re.search(r'(\"\"\").*?\1|(\'\'\').*?\2', line_note)
                        if note_obj:
                            note = note_obj.group()
                            for server in servers:
                                #note = __import__(m_file.group(1)).__doc__
                                #if not note: continue
                                if re.search('%s' %server, note):
                                    if not modules:
                                        #if re.search('^test_.+\.py$', filename):
                                        if comp.search(filename):
                                            matched_files.append(filename)
                                            matched_dirs.append(thisdir)
                                    else:
                                        for module in modules:
                                            #if re.search('^test_.*%s.*\.py$' %module, filename):
                                            if re.search('.*%s.*' %module, filename):
                                                matched_files.append(filename)
                                                matched_dirs.append(thisdir)
                        else:
                            pass
                else:
                    if not modules:
                        #if re.search('^test_.+\.py$', filename):
                        if comp.search(filename):
                            matched_files.append(filename)
                            matched_dirs.append(thisdir)
                    else:
                        for module in modules:
                            if re.search('.*%s.*' %module, filename):
                                matched_files.append(filename)
                                matched_dirs.append(thisdir)
    return (matched_files, matched_dirs)
                

def load_tests(dir, modules, servers, all_suites):
    '''
    Load tests from proper dirs and modules and return test suites.
    '''
    all_matched = walk_dir(dir, modules, servers)
    matched_files = all_matched[0]
    matched_dirs = all_matched[1]
    for i in range(len(matched_dirs)):
        os.chdir(matched_dirs[i])
        print 'Selected module:  ', matched_files[i]
        #matched_module = re.search('(^test_.+)\.py', matched_files[i]).group(1)
        matched_module = matched_files[i].rstrip('py').rstrip('.')
        all_suites.append(unittest.defaultTestLoader.loadTestsFromName(matched_module))
    return all_suites


def load_suites(**kwargs):
    '''
    Discover all qualified test modules in matched directories and load them to test suites.
    '''
    all_suites = []
    current_dir = os.getcwd()
    if kwargs.has_key('-m'):
        modu_list = kwargs['-m'].split()
    else: modu_list = None
    if kwargs.has_key('-s'):
        serv_list = kwargs['-s'].split()
    else: serv_list = None

    if kwargs.has_key('-d'):
        dir_list = kwargs['-d'].split()
        for i in range(len(dir_list)):
            if not re.match('^\/', dir_list[i]):
                dir_list[i] = '%s/%s' %(current_dir, dir_list[i])
            all_suites = load_tests(dir_list[i], modu_list, serv_list, all_suites)
    else:
        all_suites = load_tests(current_dir, modu_list, serv_list, all_suites)
    os.chdir(current_dir)
    testSuite = unittest.TestSuite(all_suites)
    print '\nTotal number of tests in selected modules: ', testSuite.countTestCases(), '\n'
    return testSuite


def filter_suites(suites, **kwargs):
    '''
    Filtrate the testcases with specified keyword then load them to test suites.
    '''
    for suite in suites:
        tests = suite._tests
        if len(tests):
            for test in tests:
                testcases = test._tests
                filtered_tests = []
                for t in testcases:
                    method = t.__dict__
                    if '_testMethodName' in method:
                        method_name = method['_testMethodName']
                        if kwargs.has_key('-p'):
                            prio = kwargs['-p']
                            prio_list = prio.split()
                        else: prio = None
                        if kwargs.has_key('-t'):
                            func = kwargs['-t']
                            func_list = func.split()
                        else: func = None
                        if not prio and not func:
                            print 'Selected testcase:  ', method_name
                            filtered_tests.append(t)
                            pass
                        elif prio and not func:
                            for i in prio_list:
                                if re.search('^test_.+_%s$' %i, method_name):
                                    print 'Selected testcase:  ', method_name
                                    filtered_tests.append(t)
                        elif func and not prio:
                            for j in func_list:
                                #if re.search('^test.*_%s_.+' %j, method_name):
                                if re.search('.*%s.*' %j, method_name):
                                    print 'Selected testcase:  ', method_name
                                    filtered_tests.append(t)
                        elif prio and func:
                            for i in prio_list:
                                if re.search('^test_.+_%s$' %i, method_name):
                                    for j in func_list:
                                        if re.search('.*%s.*' %j, method_name):
                                            print 'Selected testcase:  ', method_name
                                            filtered_tests.append(t)
                        else:
                            print 'Not match any criteria, this is just for test.'
                    else:
                        raise Exception('No key "_testMethodName" found in method, exit.')
                        sys.exit()
                test._tests = filtered_tests
    testSuite = unittest.TestSuite(suites)
    #print '\nTotal number of tests in filtered test suite: ', testSuite.countTestCases()
    print '\nTotal number of selected testcases to run: ', testSuite.countTestCases()
    return testSuite
                        

def run_tests(testSuite):
    '''
    Run all extracted testcases.
    '''
    xmlrunner.XMLTestRunner(output='/tmp/output/test-reports', descriptions=False, verbose=True).run(testSuite)


def usage():
    print """
    Usage: python runtest [OPTION VALUE]
           1.The OPTION and VALUE are optional, if no OPTION provided, all testcases
           under current directory including sub-directories will be run.
           2.If OPTION is provided, VALUE MUST be fowllowed.
           3.Multiple VALUEs MUST be wrapped in quotes. Space character MUST be used to separate each VALUE.
           Example: python runall -d 'tms_xxx /root/home' -p 'HIGH MEDIUM' -t 'task Endpoint' -m ios -s CCS
           
    -h: Display the help.
    -d: Specify the directory/directories where testcases are selected from.
        The directory name MUST contain absolute path(AP).
    -m: Select modules with specified module keyword marked in module file name.
    -t: Select testcases with specified testcase keyword marked in testcase name.
    -p: Select testcases with specified priority keyword marked in testcase name.
        The priority keyword MUST be in 'HIGH', 'MEDIUM' and 'LOW'.
    -s: Specify the cluster server on which the tests are to be run.
        The server keyword MUST be server name with capital letter, such as 'MES','CCS'.
        The server keyword MUST be marked in test module's "documentation strings".
        Besides server keyword, any other word in the documentation strings can be used
        by this option to fileter module.
    """


def main():
    add_path()
    opts, args = getopt.getopt(sys.argv[1:], 'hd:m:t:p:s:')
    d_args = {}
    if args:
        print 'Unrecognized option, please use -h for help.'
        sys.exit()
    elif not opts:
        print 'No argument detected, will be running all tests......'
        time.sleep(10)
        print "Start time:  %s" %time.ctime(), '\n'
        testsuite = load_suites(**d_args)
        run_tests(testsuite)
    elif opts:
        try:
            for key, value in opts:
                if key == '-h': usage(), sys.exit()
                else: d_args[key] = value
        except Exception, e:
            print e.message
            usage()
        else:
            print "Start time:  %s" %time.ctime(), '\n'
            testsuite = load_suites(**d_args)
            filtered_suites = filter_suites(testsuite, **d_args)
            run_tests(filtered_suites)
    print "End time:  %s" %time.ctime(), '\n'
        


if __name__ == '__main__':
    main()


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值