awk脚本创建xml文件

时间:2018-02-19 13:01:48

标签: xml awk junit

我简化了我的问题。

我有一个包含以下数据的文本文件

package1| class1 | test case1 |  Pass  |  endpoint | ref no  |  
package1| class1 | test case2 |  Pass  |  endpoint | ref no  |  
package2| class2 | test case1 |  Fail  |  endpoint | ref no  | fail reason  
package3| class3 | test case2 |        |           |         |

我想从上面创建一个xml,如下所示。 当field1与前一行field1不同时,逻辑创建一个 节点并在其下测试案例。如果字段4为空则则将测试计为错误。我想在包级别即 节点处保持测试用例中没有错误和没有失败的计数。并且还在每个 节点上保持测试用例的计数,没有错误和没有失败

<?xml version="1.0" encoding="UTF-8"?>
<testsuites errors="1" failures="1" tests="4">
  <testsuite name="package1" errors="0" failures="0" tests="2">
    <Testcase>
       <class>class1</class>
       <name>Testcase1</name>
       <Result>Pass</Result>
       <FailReason></FailReason>
    </testcase>
    <Testcase>
      <class>class2</class>
      <name>Testcase2</name>
      <Result>Pass</Result>
      <FailReason></FailReason>
      </testcase>
 </TestSuite>

 <testsuite name="package2" errors="0" failures="1" tests="1">
  <Testcase>
    <class>class1</class>
    <name>Testcase1</name>
    <Result>Fail</Result>
    <FailReason>FailReason</FailReason>
  </testcase>
 </TestSuite>

 <testsuite name="package3" errors="1" failures="0" tests="1">
  <Testcase>
    <class>class1</class>
    <name>Testcase1</name>
    <Result>Fail</Result>
    <FailReason>Error</FailReason>
  </testcase>
 </TestSuite>
</Testsuites>

`

我正在使用awk来创建尝试了这么多代码没什么成功的,我不知道我应该把这个代码放在这里我尝试了近6个小时的工作,它无法弄清楚如何去干现在。任何帮助表示赞赏。 任何脚本解决方案都不仅仅是awk。

2 个答案:

答案 0 :(得分:2)

请注意,这不是您问题的完整答案。我觉得在一次运行中将整个答案作为一个完整的程序分享我感觉不舒服:要评论的代码太长了。

请回来告诉我,如果你到目前为止都在遵守这些代码,如果被问到,我会通过编辑我的答案来补充说明。

首先:我摆脱了原始输入文件中所有空格的先验。它现在看起来像这样:

package1|class1|test case1|Pass|endpoint|ref no|  
package1|class1|test case2|Pass|endpoint|ref no|  
package2|class2|test case1|Fail|endpoint|ref no|fail reason  
package3|class3|test case2|    |        |      |

然后,我将字段分隔符设置为管道并继续进行一些处理。正如许多人已经指出的那样,您的输入文件不一致,并且您的xml不兼容。我愿意留下所有实际实施(根据SO指南,以便您可以展示您的努力)

尝试这样的事情:创建一个脚本(您将其称为awk -f script.awk textfilewithdata.txt)并使其听起来像:

BEGIN {
    FS = "|"
    numberOfPackages = 0
    fails = "fails"
    testcases = "testcases"
}

{
    allTests++
    if ($1 != currPackage) {
        currPackage = $1
        numberOfPackages++
        if (!(currPackage in packages)) {
            # creates it
            packages[currPackage][testcases] = 0    # stores errors, failures and test
            packages[currPackage][fails] = 0
            }
        packages[currPackage][testcases]++
        if ($4 == "Fail" ) {packages[currPackage][fails]++;allFail++}
    } else {
        packages[currPackage][testcases]++
        if ($4 == "Fail" ) {packages[currPackage][fails]++;allFail++}
    }
}

END {
    print "<?xml version="1.0" encoding="UTF-8"?>"
    print "<testsuites failures=\""allFail"\" tests=\""allTests"\">"
    for (j in packages) {
        print "\t<testsuite name=\""j"\"  failures=\""packages[j][fails]"\" tests=\""packages[j][testcases]"\">"
        for (k in packages[j]) {
            print "\t\t<Testcase>"
            print "\t\t\t<class>"
            print "\t\t<\\Testcase>"
        }
        print "\t<\\testsuite>"
    }
}

再次,请回复我的评论,我将尝试提供有关上述代码的解释。

输出看起来像这样(gawk 4.2,Windows 10)

<?xml version=1 encoding=-8?>
<testsuites failures="1" tests="4">
        <testsuite name="package1"  failures="0" tests="2">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>
        <testsuite name="package2"  failures="1" tests="1">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>
        <testsuite name="package3"  failures="0" tests="1">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>

答案 1 :(得分:0)

这是产生junit测试报告类型xml的最终解决方案。几乎两天的努力找到答案但是很好地了解了awk:)

输入

012_project_y2013 | 01_12.1_new_prodcodes | tc06_s2m_mc_0200_MBT.utt |  Pass  |  MIG_MSI_EP1 MDS_S2A_EP1 |
012_project_y2013 | 01_12.1_new_prodcodes | tc07_s2m_mc_0200_MCW.utt |  Fail  |                          |
012_project_y2013 | 01_12.1_new_prodcodes | tc08_s2m_mc_0200_MCW.utt |  |  |
012_project_y2014 | 01_12.1_new_prodcodes | tc09_s2m_mc_0200_MCW.utt |  |  |

BEGIN {
    FS = "|"
}NF==0 {next}
NF>=1{
        allTests +=1;
    if ($1 != package) {
        package = $1;
        class = $2;
        testname = $3;
        testresult = $4;
        endpoint = $5;
        rrn = $6;
        failreason=$7
        numberOfPackages +=1;

        if(!(package in currPackage)){

                if(length(prepkg)!=0){
                testsuite[prepkg,tests,fails,errors];}
                prepkg = package;
                tests=0;
                fails=0;
                errors=0;
                test_result[package,"fail"] = 0;
                test_result[package,"error"] =0;
                test_result[package,"testcase"]=0;

                testcount =0;
            }

}

#       testcase +=1;

        if ($4~/Fail/) {test_result[package,"fail"]  +=1;fails +=1;allFail++}

        if ($4~/^[ ]*$/) {$4="Fail";test_result[package,"error"] +=1; errors +=1;allErrors++}

        if($7~/^[ ]*$/ || $7 == ""){failreason = "error";}

        if($7~/^[ ]*$/ || $7 == ""){failreason = "error";}

        tests +=1;
        currPackage[package,$2,$3,$4,failreason];
        test_result[package,"testcase"]++;

}
END {

                testsuite[package,tests,fails,errors];
    print "<?xml version="1.0" encoding="UTF-8"?>"

    print "<testsuites errors=\""allErrors"\" failures=\""allFail"\" tests=\""allTests"\">"
                for (k in testsuite)
                {
                        split(k,tno,SUBSEP);
                        pname = tno[1];
                        testcnt = tno[2];
                        failcnt = tno[3];
                        errcnt = tno[4];
                        print "\t<testsuite errors=\42"errcnt"\42"" " "failures=\42"failcnt"\42"" " "hostname=\42localhost\42  id=\"0\42  name=\42"pname"\42"" ""package=\42"pname"\42"" " "tests=\42"testcnt"\42"" " "timestamp=\42"date"\42"">";

                        for (y in currPackage)
                        {
                                split(y,sep,SUBSEP);
                                if (pname == sep[1]){
                                print "\t\t<testcase classname=\42"sep[2]"\42"" " "name=\42"sep[3]"\42"" " "time=\42"10"\42"">"
                                tresult = sep[4];
                                reason = sep[5];
                                        if(tresult~/Fail/)
                                        {
                                                                                                            print "\t\t\t<failure message=\42""Assertion FAILED""\42"" " "type=\42""failure""\42"">"reason"</failure>\n";
                                        }
                                }
                        }
                        print  "\t</testsuite>";
                }
                print "</testsuites>";

        }

输出

<?xml version=1 encoding=-8?>
<testsuites errors="2" failures="1" tests="4">
        <testsuite errors="1" failures="0" hostname="localhost"  id="0"  name="012_project_y2014 " package="012_project_y2014 " tests="1" timestamp="">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc09_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

        </testsuite>
        <testsuite errors="1" failures="1" hostname="localhost"  id="0"  name="012_project_y2013 " package="012_project_y2013 " tests="3" timestamp="">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc07_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

                <testcase classname=" 01_12.1_new_prodcodes " name=" tc06_s2m_mc_0200_MBT.utt " time="10">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc08_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

        </testsuite>
</testsuites>