前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Appium系列(四十)测试报告支持展示测试用例执行历史记录

Appium系列(四十)测试报告支持展示测试用例执行历史记录

作者头像
雷子
发布2021-07-29 14:59:19
4680
发布2021-07-29 14:59:19
举报

前言

之前的文章呢,我们做了数据的存储,以及如何在测试报告中展示,那么这次我们分享如何将测试用例执行结果的历史记录也展示出来。

正文

我们在执行用例时候,每次执行完毕后,如果没有及时将测试结果备份,那么下次再来执行的时候,就不知道上一次的结果。我们也看不到历史执行中的结果的趋势,有些数据不好分析。那么我们应该怎么做,让我们的测试报告可以支持呢。答案也很简单。

我们在测试用例执行的完毕的时候,我们记录测试结果,然后下次执行的时候,有历史记录我们就读取历史记录即可。

我们用BSTestRunner.py为例去讲解。

第一步:记录测试用例执行数据

为了更加灵活呢,我们在类初始化的时候呢,默认有一个是否展示,并且配置文件的路径。

代码语言:javascript
复制
class BSTestRunner(Template_mixin):
    """
    """

    def __init__(self, stream=sys.stdout, verbosity=1,
                 title=None, description=None, trynum=trynumcommonnum,
                 is_show=False,filepath=""):
        self.stream = stream
        self.verbosity = verbosity
        self.trynum = trynum
        self.is_show=is_show#是否展示
        self.filepath=filepath#测试报告历史记录存储路径
        if title is None:
            self.title = self.DEFAULT_TITLE
        else:
            self.title = title
        if description is None:
            self.description = self.DEFAULT_DESCRIPTION
        else:
            self.description = description

        self.startTime = datetime.datetime.now()

那么我们在run方法中呢,增加保存结果的代码。

代码语言:javascript
复制
    def run(self, test):
        "Run the given test case or test suite."
        result = _TestResult(self.verbosity, trynum=self.trynum)
        try:
            test(result)
        except TypeError:
            pass
        self.stopTime = datetime.datetime.now()
        #是否展示历史记录
        if self.is_show:
            name=os.path.join(self.filepath,self.stopTime.strftime('%Y_%m_%d_%H_%M_%S')+'.txt')
            with open(name,'w+') as f:
                f.write(result.success_count.__str__()+"_"+result.error_count.__str__()+"_"+result.failure_count.__str__())
                f.close()
        self.generateReport(test, result)
        print('\n测试耗时: %s' % (self.stopTime - self.startTime))
        return result

这里面我做的事,要展示历史记录才存。可以改造成自己想要的。

第二步:在测试报告中展示数据

我们收集到的数据,接下来在测试报告中就是展示了。我们在generateReport做处理。因为有展示或者不展示,不展示我们走的是老的方法。

代码语言:javascript
复制
  def generateReport(self, test, result):
        report_attrs = self.getReportAttributes(result)
        generator = 'BSTestRunner %s' % __version__
        stylesheet = self._generate_stylesheet()
        heading = self._generate_heading(report_attrs)
        report = self._generate_report(result)
        ending = self._generate_ending()
        #如果展示那么我们走新的方法
        if self.is_show:
            scrpit=self.___generate_scrpitone()
        else:
            scrpit=self._generate_scrpit()
        output = self.HTML_TMPL % dict(
            title=saxutils.escape(self.title),
            generator=generator,
            stylesheet=stylesheet,
            scripts=scrpit,
            heading=heading,
            report=report,
            ending=ending
        )
        self.stream.write(output)

我们看新的产生静态html的方法

代码语言:javascript
复制
  def ___generate_scrpitone(self):
        namerun,faillist,success,error=self._readresult()
        name, cpu, mem = self._getdata()
        return self.SCRPICTDATA% dict(name=name,cpu=cpu,men=mem,
                                      reslutname=namerun,
                                      success=success,
                                      fail=faillist,
                                      error=error)

这里也很简单,有一个读取结果的方法。结果的方法。默认会返回执行结果的数据。

代码语言:javascript
复制
    def   _readresult(self):
        namerun=[]
        faillist=[]
        success=[]
        error=[]
        for root,dirs,files in os.walk(self.filepath):
            for file in files:
                if file.endswith(".txt"):
                    namerun.append(file.split(".")[0].split("/")[-1])
                    with open(os.path.join(root,file),'r') as f:
                        reslut=f.readline().split('\n')[0].split("_")
                        success.append(reslut[0])
                        error.append(reslut[1])
                        faillist.append(reslut[2])
        return namerun,faillist,success,error

那么我们看下self.SCRPICTDATA的代码,这里是关键的数据展示的地方。

代码语言:javascript
复制
 SCRPICTDATA=r"""
    <script language='javascript' type='text/javascript'>
var dom = document.getElementById('containerchart');
var myChart = echarts.init(dom);
var domone = document.getElementById('container2');
var myChartone = echarts.init(domone);
var optionsone;
optionsone = {
    title: {
        text: '历史记录'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['成功', '失败','错误']
    },
    grid: {
        left: '3%%',
        right: '4%%',
        bottom: '3%%',
        containLabel: true
    },
    toolbox: {
        feature: {
            saveAsImage: {}
        }
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: %(reslutname)s
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: '成功',
            type: 'line',
            stack: '总量',
            data: %(success)s
        },
        {
            name: '失败',
            type: 'line',
            stack: '总量',
            data: %(fail)s
        },
        {
            name: '错误',
            type: 'line',
            stack: '总量',
            data: %(error)s
        }

    ]
};
if (optionsone && typeof optionsone === 'object') {
    myChartone.setOption(optionsone);
}
var option;
option = {
    title: {
        text: '性能数据'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['cpu', '内存']
    },
    grid: {
        left: '3%%',
        right: '4%%',
        bottom: '3%%',
        containLabel: true
    },
    toolbox: {
        feature: {
            saveAsImage: {}
        }
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data:%(name)s
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: 'cpu',
            type: 'line',
            stack: '总量',
            data:%(cpu)s
        },
        {
            name: '内存',
            type: 'line',
            stack: '总量',
             data: %(men)s
        }

    ]
};

if (option && typeof option === 'object') {
    myChart.setOption(option);
}


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
    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;
}
</script>
</body>
</html>
    """

这是数据展示的方法,还有要对头部进行修改,在generateReport方法中有对应的处理方式。我们这里由于篇幅限制呢,我们先不做展示,我会把代码统一上传的。

接下来,就是在实际代码中,执行。

代码语言:javascript
复制
besautiful = BSTestRunner(title="报告",
                              description="测试报告", 
                              stream=openone,
                              trynum=runprojecttrynum,
                              is_show=ISSHOWHISTORY,
                              filepath=BASH_DIR)

修改后支持是否展示,这些配置呢,都存在了config.py中。

代码语言:javascript
复制
BASH_DIR=os.path.join(os.getcwd(),"report")
ISSHOWHISTORY=True

我们可以执行下测试用例。最后结果如下。

代码语言:javascript
复制

最新代码已经提交
https://gitee.com/liwanlei/appiumdemo

后记

发现问题,解决问题。遇到问题,慢慢解决问题即可。

欢迎关注雷子说测试开发,后续将会持续为大家分享更多的技术知识

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雷子说测试开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档