2018-04-18 Coding to generate data for Allure report

Step 1 Identify the information needed

For each test case execution, we need to collect below information:

  • start-time & end-time of entire execution
  • start-time, end-time & duration of each test case
  • name of the test script
  • execution status. 111=pass, 100=Fail, 000=Error, 101=Block
  • comment
  • location of log-files
  • feature name, can be abstracted from script name

Step 2 Decide the format of the information

  • start-time, end-time, duration, in seconds since 1970-01-01
  • script name, of type string
  • execution status, of type string
  • comment, location of logs, feature, of type string

Step 3 Collect the information

  • List all the sub-folders of current folder
    import os
    #list all the folders in this folder
    target_folder = "./logs"
    
    arr_dir = []
    for root, dirs, files in os.walk(target_folder):
        for name in dirs:
            arr_dir.append(name)
  • Build path to some log-file, then read contents of the file
    stdout_path = os.path.join(target_folder, dir_name, "stdout.txt")
    stdout_f = open(stdout_path, 'r')
    stdout_contents = stdout_f.readlines() 
  • Get the first/last line of the log
    first_line = stdout_contents[0].strip()
    last_line = stdout_contents[-1].strip()
  • Get the first/last line of the log
    first_line = stdout_contents[0].strip()
    last_line = stdout_contents[-1].strip()
  • Convert time-string like 2018-04-18 07-33-08 into seconds since 1970-01-01
    import time

    #convert string to time
    time_str = "2018-04-18 07-33-08"
    the_tick = time.strptime(the_tick, '%Y-%m-%d %H-%M-%S')

    #get time-stamp
    the_tick = time.mktime(the_tick)
  • Decide the execution result of the test case, using log content
    def abstract_script_result_from_log_line(the_line):    
        if "Result = Pass" in the_line:
            return "Pass"
        if "Result = Fail" in the_line:
            return "Fail"
        else:
            return "Error"

Step 4 Write information into XML format

    from xml.etree.ElementTree import Element, SubElement
    from xml.etree.ElementTree import Comment, tostring, ElementTree

    #build xml-element        
    result = Element('result')
    start_time = SubElement(result, 'startTime')
    start_time.text = str(script_start_time)
        
    end_time = SubElement(result, 'endTime')
    end_time.text = str(script_end_time)
        
    duration = SubElement(result, 'duration')
    duration.text = str(script_duration)[0:6]
        
    name = SubElement(result, 'name')
    name.text = script_name.strip()
        
    status = SubElement(result, 'status')
    status.text = script_status_code
        
    comment = SubElement(result, 'comment')
    comment.text = script_comment
        
    log_file = SubElement(result, 'logFile')
    log_file.text = script_log_folder
        
    class_name = SubElement(result, 'featureName')
    class_name.text = script_feature_name
    
    #write to result xml file
    meta_data = "results.xml"
    results_xml = open(meta_data, 'w')
    
    #global start-time
    results_xml.write('<results>')
    results_xml.write('<startTime>')
    results_xml.write(str(global_start_time))
    results_xml.write('</startTime>')

    results_xml.write(tostring(result))
    results_xml.write('\n')

    #global end-time
    results_xml.write('<endTime>')
    results_xml.write(str(global_end_time))
    results_xml.write('</endTime>')
    results_xml.write('</results>')

Step 5 Define a script file to convert the XML content into J-Unit format

  • Define the schema of the XML file(xlst.xsl)
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8"
        indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="results">
        <testsuites>
            <testsuite tests="{count(result/status)}" passed="{count(result[status='111'])}"
                failure="{count(result[status='100'])}" skipped="{count(result[status='101'])}"
                error="{count(result[status='000'])}" time="{endTime - startTime}">
                <xsl:for-each select="result[status='111']">
                    <testcase name="{name}" classname="{featureName}" result="{status}"
                        comments="{comment}" time="{duration}">
                        <passed />
                    </testcase>
                </xsl:for-each>
                <xsl:for-each select="result[status='000']">
                    <testcase name="{name}" classname="{featureName}" result="{status}"
                        comments="{comment}" time="{duration}">
                        <failure message="{failReason}"></failure>
                        <error />
                    </testcase>

                </xsl:for-each>
                <xsl:for-each select="result[status='100']">
                    <testcase name="{name}" classname="{featureName}" result="{status}"
                        comments="{comment}" time="{duration}">
                        <failure message="{failReason}"></failure>
                        <failure />
                    </testcase>
                </xsl:for-each>
                <xsl:for-each select="result[status='101']">
                    <testcase name="{name}" result="{status}" comments="{comment}">
                        <skipped message="Test never ran"></skipped>
                        <skipped />
                    </testcase>
                </xsl:for-each>
            </testsuite>
        </testsuites>
    </xsl:template>
</xsl:stylesheet>
  • Use Python to read and convert the XML based on the schema
from lxml import etree, objectify
import os.path
import sys

def generateJUnit(metadata):
        parser = etree.XMLParser(remove_blank_text=True)
        tree = etree.parse(metadata, parser)
        root = tree.getroot()
        for elem in root.getiterator():
            if not hasattr(elem.tag, 'find'): continue  # (1)
            i = elem.tag.find('}')
            if i >= 0:
                elem.tag = elem.tag[i + 1:]
        objectify.deannotate(root, cleanup_namespaces=True)
        tree.write(metadata,pretty_print=True, xml_declaration=True, encoding='UTF-8')
        dom = etree.parse(metadata)
        xslt = etree.parse("XLST.xsl")
        transform = etree.XSLT(xslt)
        newdom = transform(dom)
        str = etree.tostring(newdom, pretty_print=True)
        print("Generating TestResults.xml under TestEnvironment")
        with open("TestEnvironment\TestResults.xml","w")as fp:
            fp.write(str)

if __name__ == '__main__':
    metadata = sys.argv[1]
    generateJUnit(metadata)
  • Invoke the python script file
    python JUnitResultGenerator.py

Step 6 Use Allure command-line to generate the HTML report

allure-commandline\bin\allure.bat generate TestEnvironment -c -o allure-results

References:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容