main.py 10.9 KB
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys,os
import getopt
import unittest
import time
# import HTMLTestRunner
import HTMLTestRunner_cn
import commons.SendEmail as em
import commons.common as com
from commons.Logging import Logger
#DiscoveringTestLoader解决了代码在liunx无法成功加载用例的问题
from discover import DiscoveringTestLoader
log=Logger()


def Create_Testcase_suite(filename=None,testclass=None,casename=None,emailaddr=False,priority=False,casemark=None):
    '''可以拓展该方法,为读取相对路径,然后传入指定文件测试用例:
    Create_Testcase_suite(最顶层用例文件Case_Sences,下一级具体接口文件,)
    '''
    testunit=unittest.TestSuite()
    test_Loader = DiscoveringTestLoader()
    #可以通过a="./Case_Report/test2.txt" 和a="E:/EclipseWorkspace/WorksapceDemo/Request-demo/src/Case_Report/test2.txt"
    #来获取指定文件内容
    path="./testcase/"  
    if filename:
        #path=os.path.dirname(__file__)不能通过命令行获取当前文件路径,返回路径为空
        #path=os.path.dirname(__file__)
#         filename=path+"/testcase/"+filename
        filename=path+filename
        print("filename",filename)
    else:
#         listaa = "E:\\EclipseWorkspace\\nong12test\\Request-fresh\\src\\testcase\\"
        filename=path
    
    log.info("用例路径%s"%path)
    print("filename==",filename)
    #discover会展示有多少test_*.py的文件,然后for依次添加这些文件夹下test_*.py里面的testcase
    #这个方法会识别指定目录下所有test_*.py文件和test_*.py文件中所有class *(unittest.TestCase)以及其中的case
    #每一个接口文件下面都得添加一个_init_.py不然无法识别该文件下的test_*.py
    #_init_.py把所在目录当作一个package处理, from-import 语句导入子包时需要用到它。 如果没有用到, 他们可以是空文件
    #如引入package.module下的所有模块from package.module import * 
    #submitOrder文件下不加_init_.py时,test_submitOrder文件无法被搜索

    #提前设置用户自定义用例等级,提前设置全局变量以免报错
    com.set_priority(priority)
    #提前设置用户自定义用例标记,提前设置全局变量以免报错
    com.set_mark(casemark)
    #discover会把指定的文件都加载一遍,会把所有文件中class测试类外和if __name__ == "__main__"外的代码加载一遍,
    #如果测试文件中有import公共方法Case_Method.ConfigAction,系统并不会去加载公共方法内的代码
    #如果通过创建全局变量来控制case的优先级并再py文件中读取全局变量时,要提前给全局变量赋值,以免在discover用例文件时,全局变量还为空,会报错
    log.info("222222")
    if filename and testclass and casename:
        print("1-1-1")
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                if testclass in str(test_class):
                    for test_num in test_class:
                        if casename in str(test_num):
                            testunit.addTest(test_num)
                             
    elif filename and testclass and (not casename):
        print("1-1-0")
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                if testclass in str(test_class):
                    testunit.addTests(test_class)
                     
    elif filename and (not testclass) and (not casename):  
        print("1-0-0")        
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                testunit.addTests(test_class)
                 
    elif (not filename) and (not testclass) and (not casename):
        print("0-0-0") 
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                testunit.addTests(test_class)
                 
    elif (not filename) and testclass and (not casename):
        print("0-1-0") 
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                if testclass in str(test_class):
                    testunit.addTests(test_class) 
                     
    elif (not filename) and testclass and casename:
        print("0-1-1") 
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                if testclass in str(test_class):
                    for test_num in test_class:
                        if casename in str(test_num):
                            testunit.addTest(test_num)   
     
    elif filename and (not testclass) and casename:
        print("1-0-1") 
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                for test_num in test_class:
                    if casename in str(test_num):
                        testunit.addTest(test_num) 
    else:
        print("0-0-1") 
        discover=test_Loader.discover(filename,pattern='test_*.py',top_level_dir=None)
        for test_suite in discover:
            for test_class in test_suite:
                for test_num in test_class:
                    if casename in str(test_num):
                        testunit.addTest(test_num) 
        
    print(testunit)
    log.info("发送的邮件地址%s:"%emailaddr)
    log.info("运行的用例优先级%s:"%priority)
    log.info("运行的用例标记%s:"%casemark)
    log.info("测试用例加载结果%s"%testunit)

    now = time.strftime("%Y-%m-%d %H_%M_%S",time.localtime())
    #获取当前文件的路径,sys.argv[0]为当前文件 
    path=os.path.dirname(os.path.abspath(sys.argv[0])) 
    #filename="E:\\EclipseWorkspace\\nong12test\\Request-fresh\\src\\Case_Report\\"+now+"_result.html"
    report_file=path+"/report/"+now+"_result.html"
    log.info("测试报告路径%s:"%report_file)
    fp=open(report_file,'wb')
     
    runner=HTMLTestRunner_cn.HTMLTestRunner(
        stream=fp,
        title=u'搜索功能测试报告', #设置HTML报告的title
        description=u'用例执行情况:',#设置HTML报告内容中的描述
        verbosity = 2,#设置报告详细级别,设置为1时有bug,无法失败连续重跑,最好为2(已验证连续3个用例重跑)
        retry=2, #设置重跑次数,默认为0
        save_last_try=False) #为True,一个用例仅显示最后一次测试的结果;为False,则显示所有重试的结果;
          
    log.info("********运行测试用例********")
    runner.run(testunit)
    fp.close()
  
    if emailaddr:
        em.send_email(report_file,emailaddr)
    else:
        em.send_email(report_file)

def main_get(argv):
    """
        通过 getopt模块 来识别参数demo,  http://blog.csdn.net/ouyang_peng/
    """
 
    _filename = False
    _testclass = False
    _casename = False
    _emailaddr = []
    _priority = []
    _casemark = False
    
    try:
        """
            options, args = getopt.getopt(args, shortopts, longopts=[])
 
            参数args:一般是sys.argv[1:]。过滤掉sys.argv[0],它是执行脚本的名字,不算做命令行参数。
            参数shortopts:短格式分析串。例如:"hp:i:",h后面没有冒号,表示后面不带参数;p和i后面带有冒号,表示后面带参数。
            参数longopts:长格式分析串列表。例如:["help", "ip=", "port="],help后面没有等号,表示后面不带参数;ip和port后面带冒号,表示后面带参数。
 
            返回值options是以元组为元素的列表,每个元组的形式为:(选项串, 附加参数),如:('-i', '192.168.0.1')
            返回值args是个列表,其中的元素是那些不含'-'或'--'的参数。
            若命令行-c或--testclass后面不加任何值的话或报错,若-和c之间有空格,或者-c后面有连续两个参数,会导致参数不匹配
        """
        opts, args = getopt.getopt(argv, "hf:c:t:e:p:m:", ["help", "filename=", "testclass=", "casename=","emailaddr=","priority=","mark="])
        
    except getopt.GetoptError:
        print('''Error: test_arg.py -f <filename> -c <testclass> -t <casename> -e <emailaddr> -p <priority> -m <mark>''')
        print('''   or: test_arg.py  --filename=<filename> --testclass=<testclass> --casename=<casename> 
            --emailaddr=<emailaddr> --priority=<priority> --mark=<mark>''')
        sys.exit(2)
       
    # 处理 返回值options是以元组为元素的列表。
#     print "opts",opts
#     print "args",args
#     print "argv",argv
    for opt, arg in opts:
        print('opt',opt)
        print('arg',arg)
        if opt in ("-h", "--help"):
            print('''test_arg.py -f <filename> -c <testclass> -t <casename> -e <emailaddr> -p <priority> -m <mark>''')
            print('''or: test_arg.py  --filename=<filename> --testclass=<testclass> --casename=<casename> 
                --emailaddr=<emailaddr> --priority=<priority> --mark=<mark>''')
            sys.exit()
        elif opt in ("-f", "--filename"):
            _filename = arg
        elif opt in ("-c", "--testclass"):
            _testclass = arg
        elif opt in ("-t", "--casename"):
            _casename = arg
        elif opt in ("-e", "--emailaddr"):
            _emailaddr.append(arg)
        elif opt in ("-p", "--priority"):
            #arg传入的都是字符串,控制优先级时需要转换
            _priority.append(int(arg))
        elif opt in ("-m", "--mark"):
            #arg传入的都是字符串,控制优先级时需要转换
            _casemark=arg
            
    print('filename=', _filename)
    print('testclass=', _testclass)
    print('casename=', _casename)
    print('emailaddr=', _emailaddr)
    print('priority=', _priority)
    print('mark=', _casemark)
 
    print(len(sys.argv))

    # 打印 返回值args列表,即其中的元素是那些不含'-'或'--'的参数。
    for i in range(0, len(sys.argv)):
        print(u'输入参数 %s 为:%s' % (i + 1, sys.argv[i]))
 
    Create_Testcase_suite(filename=_filename,testclass=_testclass,casename=_casename,emailaddr=_emailaddr,priority=_priority,casemark=_casemark)


if __name__ == "__main__":
    # sys.argv[1:]为要处理的参数列表,里边的项为用户输入的参数,sys.argv[0]为脚本名,所以用sys.argv[1:]过滤掉脚本名。
    main_get(sys.argv[1:])