2

enter image description hereHow to convert a generated text file to Junit format(XML) using Perl

I have a text file generated which is in the format:

Tests started on Fri Oct 19 14:11:35 2018

Test File    Comparison Result

========= =================

abc.msg    FAILED

aa.msg     PASSED

bb.msg     TO BE VALIDATED

Tests finished on Fri Oct 19 14:12:01 2018

Expected JUnit Format:

Please find attached the snip with the expected xml format

I want to convert the above text file after being generated from a Perl script to an XML file using a Perl script.

Any help would be appreciated. Thanks in advance!!

enter image description here

randomguy
  • 357
  • 2
  • 9
  • What problem are you having? – ikegami Oct 23 '18 at 15:58
  • 2
    [TAP::Harness::JUnit](http://p3rl.org/TAP::Harness::JUnit)? – choroba Oct 23 '18 at 16:03
  • What should the output look like? – Shawn Oct 23 '18 at 16:56
  • The Expected output should be similiar to this: – randomguy Oct 23 '18 at 17:11
  • 1
    You should put the expected output in your question, properly formatted so it's readable. – Shawn Oct 23 '18 at 17:44
  • Added the expected XML format as a snip – randomguy Oct 23 '18 at 18:51
  • Hi @ernix , the solution which you gave me works absolutely fine. However I have a new case in which the generated text file has an additional field "TO BE VALIDATED" other than "PASSED" and "FAILED". The new field "TO BE VALIDATED" should be marked as "skipped" in the generated xml file. Any help would be much appreciated. Thanks in advance. I also modified the text file with changes and have attached the sample xml file. – randomguy Jan 24 '19 at 18:31
  • @randomguy Could you clarify the JUnit XML format spec? There are several self-proclaimed JUnit formats. Apache Ant doesn't have skipped elements at all (https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd), and junit5's skipped elements can't have any attributes. (https://github.com/junit-team/junit5/blob/master/platform-tests/src/test/resources/jenkins-junit.xsd) – ernix Jan 25 '19 at 06:13
  • 1
    @randomguy Anyway, according to junit5 above, I created a patch (https://gist.github.com/ernix/c692ecb3233d60947d19cac10ec9fa2a) to parse SKIP directives described in TAP format (https://testanything.org/tap-specification.html#skipping-tests). Please modify custm2tap.pl to parse `TO BE VALIDATED` and push `['ok' => '# SKIP $msg'];` to `@t`, patched `TAP::Formatter::JUnit`'s `tap2junit` command now can parse SKIP directives properly. – ernix Jan 25 '19 at 06:29
  • @ernix, I modified the custom2tap.pl script to be push @t, ['ok' => '# SKIP $msg']; But i see the generated xml contains empty names. For example: Also I have attached the expected xml format in the question above. – randomguy Jan 25 '19 at 16:55
  • 1
    @randomguy You need to install patched version of `TAP::Formatter::JUnit`, original version(0.11) of `TAP::Formatter::JUnit` doesn't parse SKIP/TODO directives. You also need to change `['ok' => '# SKIP $msg']` to `['ok' => "$msg # SKIP"]` in order to meet with your expectations. And we seriously need a XML spec(XSD) to generate, not an example. Where do you use your JUnit report? Jenkins? – ernix Jan 28 '19 at 01:56
  • yes im using the JUnit report in Jenkins. I will apply the patch and share the results...Thank you so much – randomguy Jan 28 '19 at 14:56
  • Hi @ernix, I applied the patch in the following files under C:\Perl_folder\Scripts\TAP-Formatter-JUnit-0.11\lib\TAP\Formatter\JUnit --> Result.pm, session.pm, skip, skip_nomesg. I dont see any changes with the output. Thanks in advance!! – randomguy Jan 28 '19 at 23:25
  • @randomguy I believe you have to read https://perldoc.perl.org/perlmod.html before messing around with existing CPAN modules. – ernix Jan 29 '19 at 01:17
  • The `tap2junit` method does not create the ` – Martin Thøgersen Jan 18 '21 at 14:33

1 Answers1

2

TAP::Formatter::JUnit has tap2junit command that convert TAP format text into JUnit XML. All you have to do is to create a filter that can read your test result and convert it to TAP format, just like:

custom2tap.pl

#!/usr/bin/perl
use strict;
use warnings;

my @t;
while (my $line = <STDIN>) {
    $line =~ s/\R//;

    if (my ($msg, $result) = $line =~ /^(.*?)\s*(PASSED|FAILED)$/) {
        if ($result eq 'PASSED') {
            push @t, ['ok' => $msg];
        }
        elsif ($result eq 'FAILED') {
            push @t, ['not ok' => $msg];
        }
    }

}

die "No test" if @t == 0;
printf "1..%d\n", scalar @t;

for my $i (0 .. $#t) {
    printf "%s %d - %s\n", $t[$i]->[0], $i + 1, $t[$i]->[1];
}

1;

Save your test result as customtest.txt then run cat customtest.txt | perl custom2tap.pl | tap2junit -, you can have following output:

<testsuites>
  <testsuite failures="1" errors="0" name="-" tests="3">
    <testcase name="1 - abc.msg">
      <failure message="not ok 1 - abc.msg"
               type="TestFailed"><![CDATA[not ok 1 - abc.msg]]></failure>
    </testcase>
    <testcase name="2 - aa.msg"></testcase>
    <testcase name="3 - bb.msg"></testcase>
    <system-out><![CDATA[1..3
not ok 1 - abc.msg
ok 2 - aa.msg
ok 3 - bb.msg
]]></system-out>
    <system-err></system-err>
  </testsuite>
</testsuites>

Windows

Install Strawberry Perl, so that you can use cpan command.

Install TAP::Formatter::JUnit from command prompt:

> cpan -i TAP::Formatter::JUnit

Run type customtest.txt | perl custom2tap.pl | tap2junit -

enter image description here

ernix
  • 3,442
  • 1
  • 17
  • 23
  • Thanks so much for your answer @ernix . But when I execute the command in the cmd prompt, I get the following error: "'tap2junit' is not recognized as an internal or external command". Do i need to install the library "TAP::Formatter::JUnit " ? – randomguy Oct 24 '18 at 14:22
  • @DhinakaranKannan Could you give me your system information? How did you install Perl? – ernix Oct 25 '18 at 08:14
  • My Windows system has ActivePerl 5.14.2 Build 1402. its a .msi file. Jus installed it. – randomguy Oct 25 '18 at 16:56
  • In this code, the output file is being generated in the command line. How can i generate in an file with .xml extension? Thanks in Advance!!! – randomguy Oct 25 '18 at 21:07
  • 1
    @DhinakaranKannan Try redirection: `type customtest.txt | perl custom2tap.pl | tap2junit - > result.xml` – ernix Oct 25 '18 at 22:27
  • This works in my local machine which has Strawberry Perl with TAP::Formatter::JUnit installed, but in my test client it is using ActivePerl 5.14.2 Build 1402, in which it doesn't work. Do you have any solutions for Active Perl as well without upgrading the Perl version to have it working in my test client? Thank you so much for your help!!! – randomguy Oct 29 '18 at 21:01
  • `App::FatPacker` might help you. `TAP::Formatter::JUnit` is a PurePerl module that doesn't contain any XS code, so you can pack all `TAP::Formatter::JUnit` dependencies into `tap2junit` script itself. Install `App::FatPacker` in your local machine. Download `TAP::Formatter::JUnit` tarball then extract it. Run `fatpack pack bin/tap2junit > bin/tap2junit.fatpack.pl`. Copy `bin/tap2junit.fatpack.pl` to your test client. ActivePerl on your test client could run this script without dependencies installed. – ernix Oct 29 '18 at 22:41
  • I installed the App::FatPacker module in my local machine. Then I copied the tap2junit code from here: https://github.com/gitpan/TAP-Formatter-JUnit/blob/master/bin/tap2junit to my local machine ../../perl/bin directory , then run the cmd "fatpack pack bin/tap2junit > bin/tap2junit.fatpack.pl" and a tap2junit.fatpack.pl file is generated, copied that file to the bin directory of my test client & run the cmd "type customtest.txt | perl custom2tap.pl | tap2junit - > result.xml" in the test client.I get the following error " 'tap2junit' is not recognized as an internal or external command" – randomguy Oct 30 '18 at 15:12
  • 1
    Follow: https://stackoverflow.com/questions/4727480/how-do-i-make-my-perl-scripts-act-like-normal-programs-on-windows. Double check your `PATH` environment variable. Close your command prompt window and reopen it. ...or try `type customtest.txt | perl custom2tap.pl | perl path/to/perl/bin/tap2junit.fatpack.pl - > result.xml` – ernix Oct 30 '18 at 16:36
  • Set the Path environment variable and in a new command prompt window, executed the above command "type customtest.txt | perl custom2tap.pl | perl path/to/perl/bin/tap2junit.fatpack.pl - > result.xml", an empty result.xml file is created without the contents of the customtest.txt file. Thanks in advance!!! – randomguy Oct 30 '18 at 17:56
  • Did you changed `path/to/perl/bin/tap2junit.fatpack.pl` to your actual script path? – ernix Oct 31 '18 at 07:13
  • Yes I did. This is the command I ran on my test client "C:/testset/regr\testrun>type customtest.txt | perl custom2tap.pl | perl C:/testset/regr/bin/tap2junit.fatpack.pl - > result.xml". The tap2junit.fatpack.pl is in the bin folder and my custom2tap.pl and customtest.txt files are in this directory C:/testset/regr\testrun and the empty result.xml is generated in the same. – randomguy Oct 31 '18 at 14:18
  • Could you give me the output of `type customtest.txt | custom2tap.pl` and `perl -wc C:/testset/regr/bin/tap2junit.fatpack.pl` on your test client? – ernix Oct 31 '18 at 14:33
  • When I executed the first command "type customtest.txt | custom2tap.pl" I get the following error "The process tried to write to a nonexistent pipe." And for the second command C:/testset/regr/testrun> perl -wc C:/testset/regr/bin/tap2junit.fatpack.pl" I get the following "C:/testset/regr/bin/tap2junit.fatpack.pl syntax OK." – randomguy Oct 31 '18 at 14:50
  • What about `type customtest.txt | perl custom2tap.pl` ? – ernix Oct 31 '18 at 14:56
  • For this command "type customtest.txt | perl custom2tap.pl - > result.xml", result.xml file is generated with the following output: 1..4 ok 1 - aaa.msg ok 2 - bbb.msg ok 3 - ccc.msg not ok 4 - ddd.msg – randomguy Oct 31 '18 at 15:02
  • I've just tried `App::FatPacker` on my Windows machine and figured out it is designed to be run on only UNIX/Linux environment. I'm sorry, but you should setup some Linux distro somewhere to create tap2junit.fatpack.pl. – ernix Nov 01 '18 at 01:28