博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在稳定性测试中,将测试结果持续填加进入html报告
阅读量:6224 次
发布时间:2019-06-21

本文共 8323 字,大约阅读时间需要 27 分钟。

      公司需要设计一个稳定性测试,就是一直持续的跑不同的用例,直到人为停止,用例基本完成,基本框架思路就是随机选择一个testcase,跑完后输出结果。但存在一个问题,现在的unittest或nose测试报告都是测完所有case后再输出html报告,再次运行,又生成新的,没法再原来的报告中再填加结果。

      就这样问题,基本解决思路就是直接写个生成html报告的模块,然后再次每次结果加入。正好最近在看tempest的东西,里面有个这样的模块,那就不重复造轮子了,直接拿过来用吧。

     先看看生成html_log.py文件

    

import shutiltry:    import xml.etree.cElementTree as ETexcept Exception:    import xml.etree.ElementTree as ETTYPE_OK = 0TYPE_ERROR = -1TYPE_FAIL = -2TYPE_SKIP = -3class InfoParser(object):    def __init__(self, file_path, info):        self.file_path = file_path        self.info = info    def get_state(self):        if self.info.find('... ok') != -1:            return TYPE_OK        elif self.info.find('... ERROR') != -1:            return TYPE_ERROR        elif self.info.find('... FAIL') != -1:            return TYPE_FAIL        elif self.info.find('... SKIP') != -1:            return TYPE_SKIP    def get_detail(self):        if self.get_state() == 0:            return ''        else:            offset = self.info.find('Traceback')            if offset != -1:                temp = self.info[offset:]                return temp            else:                return ''    def get_class_name(self):        temp = self.get_testcase_name()        offset = temp.rfind('.')        if offset != -1:            temp = temp[0: offset]            return temp        else:            return ''    def get_testcase_name(self):        offset = self.info.find(' ...')        if offset != -1:            temp = self.info[0: offset]            return temp        return ''    def create_new_overview_node(self, root, state, class_name):        new_node = ET.Element('tr')        root.insert(len(root.getchildren()) - 1, new_node)        # testcase name        sub_node = ET.SubElement(new_node, 'td')        sub_node.text = class_name        for x in range(5):            sub_node = ET.SubElement(new_node, 'td')            sub_node.text = '0'        return new_node    def add_overview_node_detail(self, item, state):        item[5].text = str(int(item[5].text) + 1)        if state == TYPE_FAIL:            item[1].text = str(int(item[1].text) + 1)            item[1].set('class', 'failed')        elif state == TYPE_ERROR:            item[2].text = str(int(item[2].text) + 1)            item[2].set('class', 'failed')        elif state == TYPE_SKIP:            item[3].text = str(int(item[3].text) + 1)        elif state == TYPE_OK:            item[4].text = str(int(item[4].text) + 1)    def add_to_overview(self, root, state, class_name):        iter = root.getchildren()        for item in iter:            if item[0].text == class_name:                self.add_overview_node_detail(item, state)                # handle total                total_item = root[len(root.getchildren()) - 1]                self.add_overview_node_detail(total_item, state)                return        new_item = self.create_new_overview_node(root, state, class_name)        self.add_overview_node_detail(new_item, state)        # handle total        total_item = root[len(root.getchildren()) - 1]        self.add_overview_node_detail(total_item, state)    def add_to_failure(self, root):        new_item = ET.SubElement(root, 'section')        # name        sub_item = ET.SubElement(new_item, 'h3')        sub_item.text = self.get_testcase_name()        # details        sub_item = ET.SubElement(new_item, 'div')        sub_item.set('class', 'test-details')        detail_sub_item = ET.SubElement(sub_item, 'h4')        detail_sub_item.text = 'Detail'        detail_sub_item = ET.SubElement(sub_item, 'pre')        detail_sub_item.text = self.get_detail()    def add_to_all_tests(self, root, state):        new_item = ET.SubElement(root, 'li')        sub_item = ET.SubElement(new_item, 'a')        sub_item.text = self.get_testcase_name()        if state == TYPE_FAIL or state == TYPE_ERROR:            sub_item.set('class', 'failed')        else:            sub_item.set('class', 'success')    def write_log(self):        ret = self.get_state()        tree = ET.parse(self.file_path)        root = tree.getroot()        # add overview        self.add_to_overview(            root.find('body').find('overview').find('section').find('table'),            ret, self.get_class_name())        # add fail view        if ret == TYPE_FAIL or ret == TYPE_ERROR:            self.add_to_failure(                root.find('body').find('failure_details').                find('section').find('div'))        # add all tests        self.add_to_all_tests(            root.find('body').find('all_tests').find('section').find('ul'),            ret)        tree.write(self.file_path)def create_log_from_file(path, souce):    shutil.copyfile(souce, path)def add_log(path, info):    info_parser = InfoParser(path, info)    info_parser.write_log()def format_testrunner_info(test, info, state):    result = ''    # handle name    name = str(test)    offset_b = name.find('(')    offset_e = name.find(')')    testcase_name = 'no name'    if offset_b != -1 and offset_e != -1:        testcase_name = name[offset_b + 1: offset_e]        offset_e = name.find(' (')        if offset_e != -1:            testcase_name += '.'            testcase_name += name[0: offset_e]    result = testcase_name    if state == TYPE_OK:        result += ' ... ok\n\n'    elif state == TYPE_ERROR:        result += ' ... ERROR\n\n'    elif state == TYPE_FAIL:        result += ' ... FAIL\n\n'    elif state == TYPE_SKIP:        result += ' ... SKIP\n\n'    result += info    return resultdef add_testrunner_log(path, result, test_name):    # success    if result.wasSuccessful():        info = format_testrunner_info(test_name, 'Ran 1 test', TYPE_OK)        #info = format_testrunner_info(name,'Ran 1 test',TYPE_OK)        add_log(path, info)    # fail    for test, err in result.failures:        info = format_testrunner_info(test, err, TYPE_FAIL)        add_log(path, info)    # error    for name, err in result.errors:        info = format_testrunner_info(name, err, TYPE_ERROR)        add_log(path, info)    # skip    for test, reason in result.skipped:        info = format_testrunner_info(test, reason, TYPE_SKIP)        add_log(path, info)

  使用非常简单,使用对应的空报告模板,使生成的结果调用add_testrunner_log写入空模板中,最后就可以持续生成报告了

空模板见下面的html代码,copy下来后存成html文件即可使用

    Unit Test Report    

Overview

Class Fail Error Skip Success Total
Total 0 0 0 0 0

Failure details

Failure details

All tests

all tests

View Code

使用unittest写个示范代码如下:

import unittestimport timeimport sysimport html_logimport osimport reimport randomclass test(unittest.TestCase):    def setUp(self):        pass        def test_0001(self):                assert 1==1        def test_0002(self):                assert 2==2if __name__=='__main__':    suite=unittest.TestLoader().loadTestsFromTestCase(test)    testcases=list()    listcasedir='.'    testunit=unittest.TestSuite()          #选择case    for test_case in suite:        print test_case        f=re.match("(test_.*) \(__main__.test\)",str(test_case))        tt=f.group(1)        testcases.append(test_case)        test = random.choice(testcases)    mySuite = unittest.TestSuite()    mySuite.addTest(test)    result = unittest.TextTestRunner().run(mySuite)        #这里xx.html就是对应的空模板     if not os.path.exists('test_aa.html'):        html_log.create_log_from_file('test_aa.html', 'xx.html') #将结果持续加入到对应的html报告中    print test    html_log.add_testrunner_log('test_aa.html', result, test)

 结果如下,测试一直在进行,结果就一直会持续输入

转载于:https://www.cnblogs.com/landhu/p/6284873.html

你可能感兴趣的文章
Loopup集合类笔记
查看>>
ylbtech-LanguageSamples-Unsafe(不安全代码)
查看>>
Unable to connect to any of the specified MySQL hosts.
查看>>
Android屏幕尺寸适配注意事项
查看>>
JAVA代码中加了Try...Catch的执行顺序
查看>>
三个c#入门小程序
查看>>
docker中使用systemd
查看>>
[模拟电路] 1、模拟调制、解调电路原理
查看>>
Android Nine Patch图片及按钮背景
查看>>
在.NET中调用Oracle9i存储过程经验总结
查看>>
Eclipse崩溃后无法启动的问题解决
查看>>
Android Studio git ignore
查看>>
springmvc
查看>>
22.2. 用户认证
查看>>
1.7. User interfaces
查看>>
阿里Druid数据连接池在SSM框架中的配置使用
查看>>
基于Metronic的Bootstrap开发框架经验总结(17)-- 使用 summernote插件实现HTML文档的编辑和图片插入操作...
查看>>
Linux虚拟主机通过程序实现二级域名绑定到子目录
查看>>
7.12. cvs diff
查看>>
Android酷炫实用的开源框架(UI框架)
查看>>