0

I have simplified my question.

I have a text file with data as below

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 |        |           |         |

I want to create an xml from the above while will be like as below. logic whenever the field1 differs from previous line field1 create a node and tests cases under it. if field 4 is null then the test is counted as error.I want to keep count of no of test cases no of error and no of failure at package level ie node. and also keep count of test cases , no of error and no of failure at each node

<?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>

`

I was using awk to create tried so many code nothing sucessful , i am not sure which code should i put here which i tried almost 6 hours working on it not able to figure out how to do it and dry now. any help is appreciated. any script solution is good not only awk.

7
  • Not clear, could you please do show us expected output with all conditions in post too please. Commented Feb 19, 2018 at 14:04
  • @RavinderSingh13 i have edited the post , pls see if that is clear. your help is appreciated Commented Feb 19, 2018 at 15:04
  • Can you make your question any more concise? I'm sure the answer when it comes will be absolutely trivial but I don't have time to try to figure out what it is you're trying to do and I suspect neither does anyone else given you have no answers so far 5 hours after posting the question. Also make sure you use the same 4-space indenting for all of your sample input/output as you're using for your code and some examples so it's all clearly legible and we can copy/paste it directly for testing with. Commented Feb 19, 2018 at 18:09
  • @EdMorton I have edited and made the question clear . Commented Feb 19, 2018 at 23:44
  • You should also include what you have tried so far and make sure your posted expected output CAN be generated from your sample input (in your case idk what "errors" is in the output but I suspect you don't need it to learn how to solve your problem, and the upper/lower case in your output doesn't match your input plus "Errors" appears from nowhere as a FailReason). See How to Ask. Commented Feb 20, 2018 at 0:39

2 Answers 2

2

Please note this is not a complete answer to your question. I don't feel comfortable sharing the whole answer as a complete program in one run: it would be way too long code to comment.

Please, come back to me and tell me if you are following the code so far, I will add explanation by editing my answer, if asked.

First of all: I got rid a priori of all the spaces in your original input file. It now looks like this:

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|    |        |      |

Then, I set the field separator to pipe and proceed to do some processing. As many have already pointed out, your input file is not consistent, and your xml is not compliant. I am willing to leave to you all the actual implementation (as per SO guidelines, so that you can show your effort)

Try something like this: create a script (that you will call as awk -f script.awk textfilewithdata.txt) and make it sound like:

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>"
    }
}

Again, come back to me with comments, I'll try to provide explanations on the above code.

Output looks like this (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>
Sign up to request clarification or add additional context in comments.

6 Comments

thanks for the response. looks like i am moving in some correct direction. can you please explain if (!(currPackage in package)) where is this array package coming from
whopsie, I'm sorry. Array package is a typo. It should be packages. Also, please note that you can and should imho create valid xml with this architecture.
please see the in the post , i have progressed with your suggestion . in my terminal i am not able to use a[1][1] array as your suggestion may be the version difference . but i have used it as a[1,1,] type.
thanks your roadmap helped .i will upvote for your answer
@AbrarAhamed, consider also Accepting the answer, if it provided the solution to your question.
|
0

This is the final solution which produced the junit test report type xml.almost two days of struggle to find the answer but good learnt a lot about awk :)

input is

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>";

        }

output is

<?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>

1 Comment

Output here is quite different from output in the original question, however same principle applies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.