There is a great Perl module
Test::More that everybody uses for
unit testing. Here is the very simple script t/sample_1.t
:
use Test::More tests => 1;
fail('This test fails');
I wanted to write script that does the same thing, but without Test::More.
I've read several the docs about TAP (test anything protocol) to find out how to write the script. I've read:
Unfortunately the documentation wasn't enough. I had to examine the output of script that uses Test::More to find out that I need to output diagnostics to STDERR (there was nothing about this in the docs).
So, I have written a script that does completely the same things as the script with Test::More script. Here is the listing of t/sample_2.t
:
$| = 1;
print "1..1\n";
print "not ok 1 - This test fails\n";
print STDERR "# Failed test 'This test fails'\n";
print STDERR "# at t/sample_1.t line 3.\n";
print STDERR "# Looks like you failed 1 test of 1.\n";
exit 1;
But when using prove
these 2 scripts output different things. The line "# Failed test 'This test fails'" in prove
is displayed on different lines for different tests. Here is the screenshot:
I've written a test scripts that uses Capture::Tiny to check that STDERR, STDOUT and exit code for both scripts a identical. And the script shows that both scripts output the same things.
I've stored all the test files and a test script at GitHub repo.
My question. How should I write Perl unit test without Test::More to have the same output as with Test::More.
PS If you are interested why I need this. I need this to solve the issue of my Perl module Test::Whitespaces.
The tap interface information can be used to debug connectivity issues using tools such as tcpdump. Navigate to http:// <openstak-ip> /horizon/admin/instances / and note the following: IP address of the VM/Interface for which the associated tap interface is to be found.
TUN, namely network TUNnel, simulates a network layer device and operates in layer 3 carrying IP packets. TAP, namely network TAP, simulates a link layer device and operates in layer 2 carrying Ethernet frames. TUN is used with routing. TAP can be used to create a user space network bridge.
tunctl allows the host sysadmin to preconfigure a TUN/TAP network interface for use by a particular user. That user may open and use the network/write side of the interface, but may not change any aspects of the host side of the interface.
Tap interfaces are special software entities which tell the Linux bridge to forward Ethernet frames as it is. In other words, the virtual machines connected to tap interfaces will be able to receive raw Ethernet frames.
While I've got absolutely no frickin idea what's going on, I can get the outputs to match (visually at least) by including the following before any other output to STDERR:
print STDERR "\r";
This makes them match visually when run through prove
or plain old perl
. However, this is NOT what Test::More is doing.
The TAP you're outputting is per spec; if prove
wants to treat it differently from the TAP Test::More is outputting, I'd argue that's a bug (or at least an oddity) in prove
. Personally when I've written Test modules, I've always used Test::Builder or wrapped Test::More to output the TAP. Each of these is a core module. This seems to be what the majority of Test modules tend to do.
At last I have found out what is going on.
hobbs has advised me to use Test::Builder. I created test script with Test::Builder that worked exaclty as the script with Test::More (here it is).
Then I started examinig source code of Test::Builder to find out why the source of such behaviour. Here is the part of lib/TB2/Formatter/TAP/Base.pm file:
# Emit old style comment failure diagnostics
sub _comment_diagnostics {
my($self, $result) = @_;
...
# Start on a new line if we're being output by Test::Harness.
# Makes it easier to read
$self->$out_method("\n") if ($out_method eq 'err') and $ENV{HARNESS_ACTIVE};
$self->$diag_method($msg);
return;
}
So, this is the answer. prove
sets up special environment variable
HARNESS_ACTIVE
and Test::More and friends puts additional line break symbol
"\n" before any diagnostics that are printed to STDERR.
At last I've created test script that outputs exactly the same as the script written with Test::More. Source code of the script.
I really don't like this solution. It took me and outher peopler much time to find out what is going on. I'm sure that the task of pretty output should be solved in TAP parsers, and not in TAP producers.
=(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With