python3修改HTMLTestRunner,生成有截图的测试报告,并发送测试邮件(二)
阅读原文时间:2023年07月09日阅读:1

3. 如何将第一步得到的地址和名称 输入 进第二步里的表格中呢。。。

用上述查找元素的方法,发现HTMLTestRunner.py中REPORT_TEST_WITH_OUTPUT_TMPL是用来输出测试结果的。我们只需要将截图url和名称写进去即可。

假定我们目前已经可以定位到每个用例的具体截图,并将截图url定义为变量html,名称定义成变量name,修改HTMLTestRunner.py的代码如下:

REPORT_TEST_WITH_OUTPUT_TMPL = r"""

%(desc)s

<!--css div popup start-->  
<a class="popup\_link" onfocus='this.blur();' href="javascript:showTestDetail('div\_%(tid)s')" >  
    %(status)s</a>  
<td><a href="%(html)s" target="\_blank">%(name)s</a></td>      <!--此处修改-->  
<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>


""" # variables: (tid, Class, style, desc, status)

找到变量定义的函数:_generate_report_test,修改如下:

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,
html = html, #此处修改
name = name, #此处修改
status = self.STATUS[n],
)
rows.append(row)
if not has_output:
return

定义变量、以url格式输出变量已经搞定。接下来是给变量赋值~~

思路:依照大神们些的博客,看出函数_generate_report_test中的ue和uo代表unittest中打印日志和抛出异常日志。想到如果我把截图的url和name打印到日志中,就能够从ue和uo中很容易的提取到url和name。
开始对unittest进行改造~~

思路:我想对每条用例都输出截图,不论fail或者pass。如果用例执行正确,则只打印日志。如果用例执行错误,则打印日志并抛出异常日志。

unittest是python3自带的库,我们需要找到unittest文件夹,对case.py修改。路径:XXX(自己的python安装路径)\Python\Python36\Lib\unittest
case.py的TestCase类中增加两个方法

def screenshot():
def add(func):
具体如下:

class TestCase(object):
def screenshot(): #(一)中讲过定义截图的方法
imageName = str(time.time()) + '.png '
imagepath = '//sdcard//' + imageName
path = os.getcwd() + '\\screenshot'
if not os.path.exists(path):
os.mkdir( path)
os.system("adb shell //system//bin//screencap -p " + imagepath)
os.system('adb pull ' + imagepath + path)
print('lustrat' + path + '\\' + imageName + 'luend') #输出日志,前后加'luStrat'luEnd'特殊字符方便截取

def add(func):  #增加打印日志的方法  
    def wrapper(self, first, second, msg=None):  
        try:  
            func(self, first, second, msg=None)  
            TestCase.screenshot()

        except AssertionError:  
            TestCase.screenshot()  
            raise AssertionError(msg)  # 抛出AssertionError  
    return wrapper

然后在用到的assert方法前加@add装饰器。注意定义的func的传参与assert方法一致。如我用到了

@add        #此处修改 def assertEqual(self, first, second, msg=None): """Fail if the two objects are unequal as determined by the '==' operator. """ assertion_func = self._getAssertEqualityFunc(first, second) assertion_func(first, second, msg=msg)

至此HTMLTestRunner.py的uo和ue输出的日志就包含了print的截图地址信息

最后一步了,取出ue和uo的关于截图的url和name,并赋值给变量html和name就搞定了~~~ 

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 = e  
    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 = o      #此处修改  
    else:  
        ue = o

    script = self.REPORT\_TEST\_OUTPUT\_TMPL % dict(  
        id = tid,  
        output = saxutils.escape(str(uo)+str(ue)),  
    )  
    s= str(uo) +str(ue)      #此处修改开始  
    if s.count('png')!=0:       #判断日志中是否有图片  
        html =  s\[s.find('lustrat')+7:s.find('luend')\]  
        name =  html\[html.find('shot\\\\')+5:\]  
    else:  
        html = ' '  
        name = ' '              #此处修改结束  
    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,  
        html = html,  
        name = name,  
        status = self.STATUS\[n\],  
    )  
    rows.append(row)  
    if not has\_output:  
        return

百度云盘下载地址:unittest文件夹case.py修改链接:https://pan.baidu.com/s/1eTMJu86 密码:n19o

HTMLTestRunner.py链接:https://pan.baidu.com/s/1dGSRbg9 密码:lw0e