python

来源:互联网 发布:什么是seo是什么 编辑:程序博客网 时间:2024/05/29 09:53
#-*-coding:utf-8-*-
__author__ = 'pengfei913'
__version__ = "0.8.2"


# TODO: color stderr
# TODO: simplify javascript using ,ore than 1 class in the class attribute?


import datetime
import StringIO
import sys
import time
import unittest
from xml.sax import saxutils
import socket




# ------------------------------------------------------------------------
# The redirectors below are used to capture output during testing. Output
# sent to sys.stdout and sys.stderr are automatically captured. However
# in some cases sys.stdout is already cached before HTMLTestRunner is
# invoked (e.g. calling logging.basicConfig). In order to capture those
# output, use the redirectors for the cached stream.
#
# e.g.
#   >>> logging.basicConfig(stream=HTMLTestRunner.stdout_redirector)
#   >>>


class OutputRedirector(object):
    """ Wrapper to redirect stdout or stderr """
    def __init__(self, fp):
        self.fp = fp


    def write(self, s):
        self.fp.write(s)


    def writelines(self, lines):
        self.fp.writelines(lines)


    def flush(self):
        self.fp.flush()


stdout_redirector = OutputRedirector(sys.stdout)
stderr_redirector = OutputRedirector(sys.stderr)


class Template_mixin(object):
    STATUS = {
    0: 'pass',
    1: 'fail',
    2: 'error',
    }
    DEFAULT_TITLE = 'Unit Test Report'


    # ------------------------------------------------------------------------
    # HTML Template


    HTML_TMPL = r"""
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
<head>
    <title>%(title)s</title>
    <meta name="generator" content="%(generator)s"/>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    %(stylesheet)s
    <link href="http://project.laravel.qa.anhouse.com.cn/css/pysele/style.css" type="text/css" rel="stylesheet" />
    <script type="text/javascript" src="http://project.laravel.qa.anhouse.com.cn/js/pysele/jquery.js"></script>
    <script type="text/javascript" src="http://project.laravel.qa.anhouse.com.cn/js/pysele/quickwin.verticalbar.js" ></script>
    <script type="text/javascript" src="http://project.laravel.qa.anhouse.com.cn/js/pysele/quickwin.horizontalbar.js" ></script>
    <script type="text/javascript" src="http://project.laravel.qa.anhouse.com.cn/js/pysele/quickwin.histogram.js" ></script>
    <script src="http://project.laravel.qa.anhouse.com.cn/js/pysele/jquery.min.js"></script>
            <!--[if IE]>
            <script src="http://project.laravel.qa.anhouse.com.cn/js/pysele/excanvas.js"></script>
            <![endif]-->
            <script type="text/javascript" src="http://project.laravel.qa.anhouse.com.cn/js/pysele/pieChart.js"></script>
    </head>
<body>
<script language="javascript" type="text/javascript"><!--
output_list = Array();
/* level - 0:Summary; 1:Failed; 2:All */
function showCase(level) {
    trs = document.getElementsByTagName("tr");
    for (var i = 0; i < trs.length; i++) {
        tr = trs[i];
        id = tr.id;
        if (id.substr(0,2) == 'ft') {
            if (level < 1) {
                tr.className = 'hiddenRow';
            }
            else {
                tr.className = '';
            }
        }
        if (id.substr(0,2) == 'pt') {
            if (level > 1) {
                tr.className = '';
            }
            else {
                tr.className = 'hiddenRow';
            }
        }
    }
}




function showClassDetail(cid, count) {
    var id_list = Array(count);
    var toHide = 1;
    for (var i = 0; i < count; i++) {
        tid0 = 't' + cid.substr(1) + '.' + (i+1);
        tid = 'f' + tid0;
        tr = document.getElementById(tid);
        if (!tr) {
            tid = 'p' + tid0;
            tr = document.getElementById(tid);
        }
        id_list[i] = tid;
        if (tr.className) {
            toHide = 0;
        }
    }
    for (var i = 0; i < count; i++) {
        tid = id_list[i];
        if (toHide) {
            document.getElementById('div_'+tid).style.display = 'none'
            document.getElementById(tid).className = 'hiddenRow';
        }
        else {
            document.getElementById(tid).className = '';
        }
    }
}


function showTestDetail(div_id){
    var details_div = document.getElementById(div_id)
    var displayState = details_div.style.display
    // alert(displayState)
    if (displayState != 'block' ) {
        displayState = 'block'
        details_div.style.display = 'block'
    }
    else {
        details_div.style.display = 'none'
    }
}




function html_escape(s) {
    s = s.replace(/&/g,'&amp;');
    s = s.replace(/</g,'&lt;');
    s = s.replace(/>/g,'&gt;');
    return s;
}


/* obsoleted by detail in <div>
function showOutput(id, name) {
    var w = window.open("", //url
                    name,
                    "resizable,scrollbars,status,width=800,height=450");
    d = w.document;
    d.write("<pre>");
    d.write(html_escape(output_list[id]));
    d.write("\n");
    d.write("<a href='javascript:window.close()'>close</a>\n");
    d.write("</pre>\n");
    d.close();
}
*/
--></script>
    %(heading)s
    %(envioronment)s
    %(rsoverview)s
    %(overview)s
    %(resultchart)s
    %(report)s
    %(ending)s


  </body>
</html>
"""
    # variables: (title, generator, stylesheet, heading, report, ending)




    # ------------------------------------------------------------------------
    # Stylesheet
    #
    # alternatively use a <link> for external style sheet, e.g.
    #   <link rel="stylesheet" href="$url" type="text/css">
    STYLESHEET_TMPL = """
<style type="text/css" media="screen">
*{margin:0;padding:0;list-style-type:none;}
table th {
            font-weight: bold;
}
table td {
    text-align: center;
    vertical-align: middle;
}
 body, html{
    height: 100%;
    width: 100%;
    margin: 0; padding: 0;
}
/* -- heading ---------------------------------------------------------------------- */
h1 {font-family: "宋体" ;font-size: 300%;font-weight:bold;margin-top:40px;margin-bottom: 40px;}
.heading {
    margin-top: 0ex;
    margin-bottom: 1ex;
}
.heading .attribute {
    margin-top: 1ex;
    margin-bottom: 0;
    text-indent:12em;
}


/* -- add content ------------------------------------------------------------------------ */
p{
    text-indent: 12em;
    font-family: "宋体";
    font-size: 110%;
    font-weight: bold;
    margin-bottom: 6px;
    text-padding:10px;
}
/* -- 测试环境 ------------------------------------------------------------------------ */
 .environment table {
            height: 80%;
            width: 60%;
            margin: auto;
}
 .environment table th {
     background: sandybrown;
}
 .environment table td {
     margin: auto;
}
 .environment table {
    height: 80%;
    width: 60%;
    margin: auto;
}
/* -- 测试结果概要 ------------------------------------------------------------------------ */
.result table {
    height: 80%;
    width: 60%;
    margin: auto;
}
.result table th {
 background: sandybrown;
}
.result table td {
 margin: auto;
}
/* -- 测试用例分布: ------------------------------------------------------------------------ */
 #container{width:900px;margin:15px auto; overflow:hidden}
 #chart, #chartData{border:1px solid #333;background:#ebedf2 url("http://project.laravel.qa.anhouse.com.cn/image/pysele/gradient.png") repeat-x 0 0;}
 #chart{display:block;margin:0px 0 20px 45px;float:left;cursor:pointer;}
 #chartData{width:200px;margin:0 40px 180px 50px;float:right;border-collapse:collapse;box-shadow:0 0 1em rgba(0, 0, 0, 0.5);-moz-box-shadow:0 0 1em rgba(0, 0, 0, 0.5);-webkit-box-shadow:0 0 1em rgba(0, 0, 0, 0.5);background-position:0 -100px;}
 #chartData th, #chartData td{padding:0.5em;border:1px dotted #666;text-align:left;}
 #chartData th{border-bottom:2px solid #333;text-transform:uppercase;}
 #chartData td{cursor:pointer;}
 #chartData td.highlight{background:#e8e8e8;}
 #chartData tr:hover td{background:#f0f0f0;}
/* -- 测试结果分布: ------------------------------------------------------------------------ */
.result_r1 {
 margin-left: 280px;
 margin-top:20px;
}
/* -- css div popup ------------------------------------------------------------------------ */
a.popup_link {
}


a.popup_link:hover {
    color: red;
}


.popup_window {
    display: none;
    position: relative;
    left: 0px;
    top: 0px;
    /*border: solid #627173 1px; */
    padding: 10px;
    background-color: #FF0000;
    font-family: "Lucida Console", "Courier New", Courier, monospace;
    text-align: left;
    font-size: 8pt;
    width: 500px;
}


}
/* -- report ------------------------------------------------------------------------ */


.result_detail table {
            height: 90%;
            width: 50%;
            margin:auto;
            margin-top: 10px;
}
.result_detail table th {
 background: forestgreen;
}
.result_detail table td {
 margin:auto;
}
#show_detail_line {
    margin-top: 10ex;
    margin-bottom: 1ex;
}
#result_table {
    width: 75%;
    border-collapse: collapse;
    border: 1px solid #777;
    margin:0 auto;
}
#header_row {
    font-weight: bold;
    color: white;
    background-color: #777;
}
#result_table td {
    border: 1px solid #777;
    padding: 2px;
}
#total_row  { font-weight: bold; }
.passClass  { background-color: #6c6; }
.failClass  { background-color: #c60; }
.errorClass { background-color: #c00; }
.passCase   { color: #6c6; }
.failCase   { color: #c60; font-weight: bold; }
.errorCase  { color: #c00; font-weight: bold; }
.hiddenRow  { display: none; }
.testcase   { margin-left: 2em; }




/* -- ending ---------------------------------------------------------------------- */
.foot {
             text-align: center;
             padding:10px 0;
             color:#999;;
             font-size:10px;
             font-family: "sans-serif";
             display: 1ine;
             margin-top: 20px;
             background: #e8e8e8 none repeat scroll 0 0;
}
</style>
"""






    # ------------------------------------------------------------------------
    # Heading
    #


    HEADING_TMPL = """
        <h1 align="center">%(title)s</h1>
        <div class='heading'>
            %(parameters)s
        </div>


        """ # variables: (title, parameters, description)


    HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s:</strong> %(value)s</p>
""" # variables: (name, value)






    # ------------------------------------------------------------------------
    # Report
    #
    ENVIRONMENT_TMPL="""
         <p>测试环境:</p>
         <div class="environment" >
           <table border="1" aligin="center" >
             <tr aligin="center" width="200">
                 <th>电脑名称</th>
                 <th>IP</th>
                 <th>运行浏览器</th>
                 <th>运行环境</th>
             </tr>
             <tr>
                 <td aligin="center" width="200">
                  %(hostname)s
                 </td>
                 <td aligin="center" width="200">
                  %(ip)s
                 </td>
                 <td aligin="center" width="200">
                  %(browser)s
                 </td>
                 <td aligin="center" width="200">
                 %(url)s
                 </td>
             </tr>
           </table>
         </div>
        """
    RESULT_OVERVIEW_TMPL="""
        <p>测试结果概要:</p>
        <div class="result">
            <table aligin="center" border="1">
              <tr bgcolor="#76EE00">
                 <th aligin="center" width="200">
                  用例总数
                 </th>
                 <th aligin="center" width="200">
                  用例通过率
                 </th>
                 <th aligin="center" width="200">
                  用例失败率
                 </th>
                 <th aligin="center" width="200">
                  用例错误率
                 </th>
              </tr>
              <tr>
                 <td aligin="center" width="200">
                  %(all_count)s
                 </td>
                 <td aligin="center" width="200">
                  %(pass_rate)s
                 </td>
                 <td aligin="center" width="200">
                  %(fail_rate)s
                 </td>
                 <td aligin="center" width="200">
                  %(error_rate)s
                 </td>
              </tr>
            </table>
        </div>
            """
    OVERVIEW_TMPL="""
    <p>测试用例分布:</p>
        <style type="text/css">
            body{background:#fff;color:#333;font-family:"Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;font-size:0.9em;}
        </style>
        <div style="text-align:center;clear:both;">
        <script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
        <script src="/follow.js" type="text/javascript"></script>
        </div>
        <div id="container">
            <canvas id="chart" width="560" height="490"></canvas>
            <table id="chartData">
                <tr>
                    <th>用例模块</th><th>用例数量</th>
                </tr>
                <tr style="color:#0DA068">
                    <td>短信平台</td><td>%(Sms_count)s</td>
                </tr>
                <tr style="color:#194E9C">
                    <td>权限系统</td><td>%(Permission_count)s</td>
                </tr>
            </table>
        </div>
    """
    RESULT_CHART_TMPL="""
        <p>测试结果分布:</p>
        <style type="text/css">
        </style>
        <div class="result_r1">
            <canvas id ="myCanvas"  style="border:1px solid #d3d3d3;" ></canvas>
            <script type="text/javascript">
            var jasonData = {
                    "title": "平安好房业务测试情况",
                    "verticaltitle": "用例数(个)",
                    "horizontaltitle": "用例模块",
                    "data": 
   [{ "category": "通过", "datacollection": [{ "title": "短信平台", "count":%(Sms_pass_count)s }, { "title": "权限系统", "count": %(Permission_pass_count)s }]},
            { "category": "失败", "datacollection": [{ "title": " ", "count":  %(Sms_fail_count)s},{ "title": " ", "count": %(Permission_fail_count)s }] },
            { "category": "错误", "datacollection": [{ "title": " ", "count": %(Sms_error_count)s}, { "title": " ", "count":%(Permission_error_count)s}] }] };
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            var v = new histogram(ctx, jasonData,1);
            v.draw();
           </script>
        </div>
    """
    REPORT_TMPL = """
        <p>测试详情:</p>
        <div class="result_table">
            <table id='result_table'>
                <colgroup>
                <col align='left' />
                <col align='right' />
                <col align='right' />
                <col align='right' />
                <col align='right' />
                <col align='right' />
                </colgroup>
                <tr id='header_row'>
                    <td>Test Group/Test case</td>
                    <td>用例数</td>
                    <td>用例通过数</td>
                    <td>用例失败数</td>
                    <td>用例错误数</td>
                    <td>查看详情</td>
                    <td>截图</td>
                </tr>
            %(test_list)s
            </table>
        </div>
""" # variables: (test_list, count, Pass, fail, error)


    REPORT_CLASS_TMPL = r"""
        <tr class='%(style)s'>
            <td>%(desc)s</td>
            <td>%(count)s</td>
            <td>%(Pass)s</td>
            <td>%(fail)s</td>
            <td>%(error)s</td>
            <td><a href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td>
            <td>&nbsp;</td>
        </tr>
""" # variables: (style, desc, count, Pass, fail, error, cid)




    REPORT_TEST_WITH_OUTPUT_TMPL = r"""
        <tr id='%(tid)s' class='%(Class)s'>
            <td class='%(style)s'><div class='test_case'>%(desc)s</div></td>
            <td colspan='5' align='center'>


            <!--css div popup start-->
            <a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >
                %(status)s</a>


            <div id='div_%(tid)s' class="popup_window">
                <div style='text-align: right; color:red;cursor:pointer'>
                <a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >
                   [x]</a>
                </div>
                <pre>
                %(script)s
                </pre>
            </div>
            <!--css div popup end-->


            </td>
            <td align='center'>
                <a href="%(image)s"title="%(image)s">
                <img src="http://project.laravel.qa.anhouse.com.cn/image/pysele/test.png"height=20 width=20 border=0/></a>
            </td>
        </tr>
""" # variables: (tid, Class, style, desc, status)




    REPORT_TEST_NO_OUTPUT_TMPL = r"""
        <tr id='%(tid)s' class='%(Class)s'>
            <td class='%(style)s'><div class='test_case'>%(desc)s</div></td>
            <td colspan='5' align='center'>%(status)s</td>
        </tr>
""" # variables: (tid, Class, style, desc, status)




    REPORT_TEST_OUTPUT_TMPL = r"""
        %(id)s: %(output)s
"""
    REPORT_TEST_OUTPUT_IMAGE = r"""
        %(screenshot)s
"""
   # REPORT_TEST_OUTPUT_CASEID = r"""
    #    %(case_id)s
#""" # variables: (id, output)






    # ------------------------------------------------------------------------
    # ENDING
    #


    ENDING_TMPL = """
    <div class="foot" >
        <p>
            <image src="http://project.laravel.qa.anhouse.com.cn/image/pysele/hf-logo.png" width="127px" height="46px" margin-left="30px" />
        </p>
        <p >版权所有 © 平安好房(上海)电子商务有限公司  测试二组  &nbsp;&nbsp;Copyright © 2014 pinganfang.com All Rights Reserved
            <a hfef="###">沪ICP备 14012051号</a>
        </p>
    </div>
 """


# -------------------- The end of the Template class -------------------




TestResult = unittest.TestResult


class _TestResult(TestResult):
    # note: _TestResult is a pure representation of results.
    # It lacks the output and reporting ability compares to unittest._TextTestResult.


    def __init__(self, verbosity=1):
        TestResult.__init__(self)
        self.stdout0 = None
        self.stderr0 = None
        self.success_count = 0
        self.failure_count = 0
        self.error_count = 0
        self.verbosity = verbosity


        # result is a list of result in 4 tuple
        # (
        #   result code (0: success; 1: fail; 2: error),
        #   TestCase object,
        #   Test output (byte string),
        #   stack trace,
        # )
        self.result = []




    def startTest(self, test):
        TestResult.startTest(self, test)
        # just one buffer for both stdout and stderr
        self.outputBuffer = StringIO.StringIO()
        stdout_redirector.fp = self.outputBuffer
        stderr_redirector.fp = self.outputBuffer
        self.stdout0 = sys.stdout
        self.stderr0 = sys.stderr
        sys.stdout = stdout_redirector
        sys.stderr = stderr_redirector




    def complete_output(self):
        """
        Disconnect output redirection and return buffer.
        Safe to call multiple times.
        """
        if self.stdout0:
            sys.stdout = self.stdout0
            sys.stderr = self.stderr0
            self.stdout0 = None
            self.stderr0 = None
        return self.outputBuffer.getvalue()




    def stopTest(self, test):
        # Usually one of addSuccess, addError or addFailure would have been called.
        # But there are some path in unittest that would bypass this.
        # We must disconnect stdout in stopTest(), which is guaranteed to be called.
        self.complete_output()




    def addSuccess(self, test):
        self.success_count += 1
        TestResult.addSuccess(self, test)
        output = self.complete_output()
        self.result.append((0, test, output, ''))
        if self.verbosity > 1:
            sys.stderr.write('ok ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('.')


    def addError(self, test, err):
        self.error_count += 1
        TestResult.addError(self, test, err)
        _, _exc_str = self.errors[-1]
        output = self.complete_output()
        self.result.append((2, test, output, _exc_str))
        if self.verbosity > 1:
            sys.stderr.write('E  ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('E')


    def addFailure(self, test, err):
        self.failure_count += 1
        TestResult.addFailure(self, test, err)
        _, _exc_str = self.failures[-1]
        output = self.complete_output()
        self.result.append((1, test, output, _exc_str))
        if self.verbosity > 1:
            sys.stderr.write('F  ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('F')




class HTMLTestRunner(Template_mixin):
    """
    """
    def __init__(self, stream=sys.stdout, verbosity=1, title=None):
        self.stream = stream
        self.verbosity = verbosity
        if title is None:
            self.title = self.DEFAULT_TITLE
        else:
            self.title = title


        self.startTime = datetime.datetime.now()




    def run(self, test):
        "Run the given test case or test suite."
        result = _TestResult(self.verbosity)
        test(result)
        self.stopTime = datetime.datetime.now()
        self.generateReport(test, result)
        print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
        return result
    def sortResult(self, result_list):
        # unittest does not seems to run in any particular order.
        # Here at least we want to group them together by class.
        rmap = {}
        classes = []
        for n,t,o,e in result_list:
            cls = t.__class__
            if not rmap.has_key(cls):
                rmap[cls] = []
                classes.append(cls)
            rmap[cls].append((n,t,o,e))
        r = [(cls, rmap[cls]) for cls in classes]
        return r




    def getReportAttributes(self, result):
        """
        Return report attributes as a list of (name, value).
        Override this to add custom attributes.
        """
        startTime = str(self.startTime)[:19]
        duration = str(self.stopTime - self.startTime)
        status = []
        if result.success_count: status.append('Pass %s'    % result.success_count)
        if result.failure_count: status.append('Failure %s' % result.failure_count)
        if result.error_count:   status.append('Error %s'   % result.error_count  )
        if status:
            status = ' '.join(status)
        else:
            status = 'none'
        return [
            ('Start Time', startTime),
            ('Duration', duration),
            ('Status', status),
        ]


    def generateReport(self, test, result):
        report_attrs = self.getReportAttributes(result)
        generator = 'HTMLTestRunner %s' % __version__
        stylesheet = self._generate_stylesheet()
        heading = self._generate_heading(report_attrs)
        envioronment=self._generate_Environment()
        rsoverview=self._generate_RsOverview(result)
        overview=self._generate_Overview(result)
        resultchart=self._generate_Resultchart(result)
        report = self._generate_report(result)
        ending = self._generate_ending()
        output = self.HTML_TMPL % dict(
            title = saxutils.escape(self.title),
            generator = generator,
            stylesheet = stylesheet,
            heading = heading,
            overview=overview,
            resultchart=resultchart,
envioronment=envioronment,
            rsoverview=rsoverview,
            report = report,
            ending = ending,
        )
        self.stream.write(output.encode('utf8'))
    def _generate_Environment(self):
        hostname=socket.gethostname()
        ip=socket.gethostbyname(hostname)
        url="http://www.pinganfang.com/"
        browser="chrome浏览器"
        envioronment=self.ENVIRONMENT_TMPL % dict(
    ip=ip,
hostname=hostname,
            url=url,
            browser=browser,
)
        return envioronment
    def _generate_RsOverview(self,result):
        rows = []
        sortedResult = self.sortResult(result.result)
        for cid, (cls, cls_results) in enumerate(sortedResult):
            # subtotal for a class
            np = nf = ne = 0
            for n,t,o,e in cls_results:
                if n == 0: np += 1
                elif n == 1: nf += 1
                else: ne += 1


            # format class description
            if cls.__module__ == "__main__":
                name = cls.__name__
            else:
                name = "%s.%s" % (cls.__module__, cls.__name__)
            doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
            desc = doc and '%s: %s' % (name, doc) or name


            row = self.REPORT_CLASS_TMPL % dict(
                style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
                desc = desc,
                count = np+nf+ne,
                Pass = np,
                fail = nf,
                error = ne,
                cid = 'c%s' % (cid+1),
            )
            rows.append(row)


            for tid, (n,t,o,e) in enumerate(cls_results):
                self._generate_report_test(rows, cid, tid, n, t, o, e)
        all_count= result.success_count+result.failure_count+result.error_count
        Pass=result.success_count
        fail = result.failure_count
        error = result.error_count
        pass_rate=Pass/all_count
        fail_rate=fail/all_count
        error_rate=error/all_count
        rsoverview = self.RESULT_OVERVIEW_TMPL % dict(
            all_count=all_count,
            pass_rate=pass_rate*'100%',
            fail_rate=fail_rate*'100%',
            error_rate=error_rate*'100%',
        )
        return rsoverview
    def _generate_Overview(self,result):
        rows = []
        sortedResult = self.sortResult(result.result)
        x={}
        for cid, (cls, cls_results) in enumerate(sortedResult):
            # subtotal for a class
            np = nf = ne = 0
            for n,t,o,e in cls_results:
                if n == 0: np += 1
                elif n == 1: nf += 1
                else: ne += 1


            # format class description
            if cls.__module__ == "__main__":
                name = cls.__name__
            else:
                name = "%s.%s" % (cls.__module__, cls.__name__)
            doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
            desc = doc and '%s: %s' % (name, doc) or name
            module=desc.split('.')[1]
            x[module]=np+nf+ne
        z={'Sms':0,'Permission':0}
        for i in z.keys():
            if i in x.keys():
                z[i]=x[i]
            else:
                 z[i]=0
        overview=self.OVERVIEW_TMPL % dict(
            Sms_count=z['Sms'],
            Permission_count=z['Permission'],
        )
        return overview
    def _generate_Resultchart(self,result):
        rows = []
        sortedResult = self.sortResult(result.result)
        x={}
        b={}
        c={}
        d={}
        for cid, (cls, cls_results) in enumerate(sortedResult):
            # subtotal for a class
            np = nf = ne = 0
            for n,t,o,e in cls_results:
                if n == 0: np += 1
                elif n == 1: nf += 1
                else: ne += 1


            # format class description
            if cls.__module__ == "__main__":
                name = cls.__name__
            else:
                name = "%s.%s" % (cls.__module__, cls.__name__)
            doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
            desc = doc and '%s: %s' % (name, doc) or name
            module=desc.split('.')[1]
            x[module]=np+nf+ne
            b[module]=np
            c[module]=nf
            d[module]=ne
            z={'Sms':0,'Permission':0}
            p={'Sms':0,'Permission':0}
            f={'Sms':0,'Permission':0}
            e={'Sms':0,'Permission':0}
            for i in z.keys():
                if i in x.keys():
                    p[i]=b[i]
                    f[i]=c[i]
                    e[i]=d[i]
                else:
                     p[i]=0
                     f[i]=0
                     e[i]=0
            rschart=self.RESULT_CHART_TMPL % dict (
                Sms_pass_count=p['Sms'],
                Sms_fail_count=f['Sms'],
                Sms_error_count=e['Sms'],
                Permission_pass_count=p['Permission'],
                Permission_fail_count=f['Permission'],
                Permission_error_count=e['Permission'],
            )
        return rschart
    def _generate_stylesheet(self):
        return self.STYLESHEET_TMPL


    def _generate_heading(self, report_attrs):
        a_lines = []
        for name, value in report_attrs:
            line = self.HEADING_ATTRIBUTE_TMPL % dict(
                    name = saxutils.escape(name),
                    value = saxutils.escape(value),
                )
            a_lines.append(line)
        heading = self.HEADING_TMPL % dict(
            title = saxutils.escape(self.title),
            parameters = ''.join(a_lines),
        )
        return heading
    def _generate_report(self, result):
        rows = []
        sortedResult = self.sortResult(result.result)
        for cid, (cls, cls_results) in enumerate(sortedResult):
            # subtotal for a class
            np = nf = ne = 0
            for n,t,o,e in cls_results:
                if n == 0: np += 1
                elif n == 1: nf += 1
                else: ne += 1


            # format class description
            if cls.__module__ == "__main__":
                name = cls.__name__
            else:
                name = "%s.%s" % (cls.__module__, cls.__name__)
            doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
            desc = doc and '%s: %s' % (name, doc) or name


            row = self.REPORT_CLASS_TMPL % dict(
                style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
                desc = desc,
                count = np+nf+ne,
                Pass = np,
                fail = nf,
                error = ne,
                cid = 'c%s' % (cid+1),
            )
            rows.append(row)


            for tid, (n,t,o,e) in enumerate(cls_results):
                self._generate_report_test(rows, cid, tid, n, t, o, e)


        report = self.REPORT_TMPL % dict(
            test_list = ''.join(rows),
            count = str(result.success_count+result.failure_count+result.error_count),
            Pass = str(result.success_count),
            fail = str(result.failure_count),
            error = str(result.error_count),
        )
        return report




    def _generate_report_test(self, rows, cid, tid, n, t, o, e):
        # e.g. 'pt1.1', 'ft1.1', etc
        has_output = bool(o or e)
        tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)
        name = t.id().split('.')[-1]
        doc = t.shortDescription() or ""
        desc = doc and ('%s: %s' % (name, doc)) or name
        tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL


        # o and e should be byte string because they are collected from stdout and stderr?
        if isinstance(o,str):
            # TODO: some problem with 'string_escape': it escape \n and mess up formating
            # uo = unicode(o.encode('string_escape'))
            uo = o.decode('latin-1')
        else:
            uo = o
        if isinstance(e,str):
            # TODO: some problem with 'string_escape': it escape \n and mess up formating
            # ue = unicode(e.encode('string_escape'))
            ue = e.decode('latin-1')
        else:
            ue = e


        script = self.REPORT_TEST_OUTPUT_TMPL % dict(
            id = tid,
            output = saxutils.escape(uo+ue),
        )
        image=self.REPORT_TEST_OUTPUT_IMAGE %dict(
            screenshot=saxutils.escape(uo+ue),
        )
     #   caseid=self.REPORT_TEST_OUTPUT_CASEID %dict(
       #     case_id=saxutils.escape(uo+ue),
      #  )




        row = tmpl % dict(
            tid = tid,
            Class = (n == 0 and 'hiddenRow' or 'none'),
            style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),
            desc = desc,
            script = script,
            image=image[image.find("image"):(int(image.find("png"))+3)],
            #caseid=caseid[caseid.find("case"):(int(caseid.find("case"))+9)],
            status = self.STATUS[n],
        )
        rows.append(row)
        if not has_output:
            return


    def _generate_ending(self):
        return self.ENDING_TMPL




##############################################################################
# Facilities for running tests from the command line
##############################################################################


# Note: Reuse unittest.TestProgram to launch test. In the future we may
# build our own launcher to support more specific command line
# parameters like test title, CSS, etc.
class TestProgram(unittest.TestProgram):
    """
    A variation of the unittest.TestProgram. Please refer to the base
    class for command line parameters.
    """
    def runTests(self):
        # Pick HTMLTestRunner as the default test runner.
        # base class's testRunner parameter is not useful because it means
        # we have to instantiate HTMLTestRunner before we know self.verbosity.
        if self.testRunner is None:
            self.testRunner = HTMLTestRunner(verbosity=self.verbosity)
        unittest.TestProgram.runTests(self)


main = TestProgram


##############################################################################
# Executing this module from the command line
##############################################################################


if __name__ == "__main__":

    main(module=None)





all_tests

#-*-coding:utf-8-*-
__author__ = 'pengfei913'
#coding=utf-8
import sys ,re ,os,math
import time
reload(sys)
sys.setdefaultencoding("utf-8")
import datetime
import logging
u=os.getcwd()
sys.path.append(u)
from test_case import *
import unittest
import HTMLTestRunner
import allcase_list #调用数组文件




#获取数组方法
alltestnames = allcase_list.caselist()
suite = unittest.TestSuite()
#suite.addTest(alltestnames.BaiduTest('test_case'))
if __name__ == '__main__':
      for test in alltestnames:
          try:
    #最关键的就是这一句,循环执行数据数的里的用例。
               suite.addTest(unittest.defaultTestLoader.loadTestsFromName(test))
          except :
               print 'ERROR: Skipping tests from "%s".' % test
               try:
                   __import__(test)
               except ImportError:
                   print 'Could not import the test module.'
               else:
                   print 'Could not load the test suite.'
               from traceback import print_exc
               print_exc()
      print
      print 'Running the tests...'
#取当前时间
# now = time.strftime("%Y-%m-%d-%H_%M_%S",time.localtime(time.time()))
now=datetime.datetime.now()
otherStyleTime=now.strftime("%Y-%m-%d %H:%M:%S")
homedir = os.getcwd()
print homedir
#把当前时间加到报告中
filename=homedir+"\\test_result\\"+"HtmlReport"+otherStyleTime.replace(":","_")+".html"#定义个报告存放路径,支持相对路径。
fp = file(filename, 'wb')
runner =HTMLTestRunner.HTMLTestRunner(
        stream=fp,
        title=u'平安好房自动化测试报告',
        )
runner.run(suite)




allcase_list

#-*-coding:utf-8-*-
__author__ = 'pengfei913'
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
def caselist():
    alltestnames = [
   'test_case.Permission.Login',
   'test_case.Sms.Login',
   'test_case.Baidu.Login'
    ]
    print "success read case list success!!"
    return alltestnames

原创粉丝点击