简体   繁体   English

如何在 perl 中运行多个测试脚本并提供另一个测试脚本的参数?

[英]How can I run multiple tests scripts in perl giving parameters from another one?

I have being taking a look at some modules of perl, and I have seen it is kind of a standard to have a lot of tests under a folder t whith the extension .t .我一直在查看 perl 的一些模块,并且我看到在扩展名为.t的文件夹t下进行大量测试是一种标准。

Those scripts can be executed directly with perl <test>.t .这些脚本可以直接使用perl <test>.t

I want to do a little framework to test one application.我想做一个小框架来测试一个应用程序。 I want to have many simple tests.我想进行许多简单的测试。 And then a main script which calls this tests to validate everything at once, but still being able to run the little tests individually without having to disable manually the other tests in the main script.然后是一个主脚本,它调用这个测试来一次验证所有内容,但仍然能够单独运行小测试,而无需手动禁用主脚本中的其他测试。

My question is how should I do this calling?我的问题是我应该怎么做这个电话? As suggested in How do I run a Perl script from within a Perl script?正如如何从 Perl 脚本中运行 Perl 脚本中所建议的那样 this interprocess communication should be avoided and instead use modules but that would make not possible to run the tests directly.应该避免这种进程间通信,而是使用模块,但这将无法直接运行测试。

My guess was to do something as follows.我的猜测是做如下事情。 In an example where I need to give some parameters in a selenium script This is the folder structure:在我需要在 selenium 脚本中提供一些参数的示例中,这是文件夹结构:

├── main_script.pl
└── t
    ├── 00-Test_1.t
    ├── 01-Test_2.t
    ├── 02-Test_3.t
    └── 03-Test_4.t

And I would call them like this:我会这样称呼他们:

system($^X, "./t/00-Test_1.t", "-b $browser", "-s $server", "-d $debug");
my $results = capture($^X, "./t/00-Test_1.t", "-b $browser", "-s $server", "-d $debug";
$log->info("Result is $results");

And each test would have something like this:每个测试都会有这样的东西:

my ($browser, $server, $debug);
GetOptions(
    'debug|d'                   => \$debug,
    'debug|d'                   => \$trace,
    'trace|t'                   => \$browser,
    'server|s=s'                => \$server,
) or die "[ERROR] Invalid options passed to $0\n";

Is this a correct approach or is there something more appropiate for doing this using modules?这是一种正确的方法还是有更适合使用模块的方法?

You already have " a main script which calls this tests to validate everything at once, but still being able to run the little tests individually " as part of the standard Perl distribution.作为标准 Perl 发行版的一部分,您已经拥有“一个调用此测试以立即验证所有内容的主脚本,但仍然能够单独运行小测试”。 It's called prove .这叫做prove

Running prove with no parameters will run all test scripts matching t/*.t (so you want the tests in a t/ subdirectory when you run prove , not in the same directory), or you can use prove t/00-Test_1.t to run a single test script.运行prove不带参数运行所有测试脚本匹配t/*.t (所以你要在测试中t/子目录当您运行prove ,而不是在同一个目录下),或者您可以使用prove t/00-Test_1.t运行单个测试脚本。

Note that prove expects the test scripts to emit output in TAP ("Test Anything Protocol") format, which is usually accomplished by using Test::More or other Test::* modules in the test scripts.请注意, prove期望测试脚本以 TAP(“测试任何协议”)格式发出输出,这通常通过在测试脚本中使用Test::More或其他 Test::* 模块来完成。

If you follow the convention of putting your application-specific modules in a lib/ subdirectory, then running prove -l will add them to @INC to make them available when running the test scripts.如果您遵循将特定于应用程序的模块放在lib/子目录中的约定,那么运行prove -l会将它们添加到@INC以在运行测试脚本时使它们可用。 ie, IE,

Root directory (run `prove` from here)
├── lib
|   └── MyProject
|       └── MyModule.pm
└── t
    ├── 00-Test_1.t
    ├── 01-Test_2.t
    ├── 02-Test_3.t
    └── 03-Test_4.t

Although the answer of @Dave Sherhman is good enough, I will post how I made it work for my project together with the suggestion of @simbabque.尽管@Dave Sherhman 的回答已经足够好,但我会在@simbabque 的建议下发布我是如何让它为我的项目工作的。 As it took me a while to understand how it works and maybe it helps another one save some time:因为我花了一段时间才理解它是如何工作的,也许它可以帮助另一个人节省一些时间:

My *.t script are now as the following script.我的*.t脚本现在是以下脚本。 Where I specify the number of tests that are inside it, and also I can give some input parameters:我在其中指定其中的测试数量,并且我还可以提供一些输入参数:

use strict;
use warnings;

use Test::More tests => 2;

use Getopt::Long qw(GetOptions);
use Drivers::Driver;
use Data::Dumper;

my ($browser, $server, $debug, $trace, $user, $password);
GetOptions(
    'debug|d'                   => \$debug,
    'trace|t'                   => \$trace,
    'user|u:s'                  => \$user,
    'password|p:s'              => \$password,
    'browser|b=s'               => \$browser,
    'server|s=s'                => \$server,
) or die "[ERROR] Invalid options passed to $0\n";

ok(do_some_test($browser) == 1);
ok(do_another_test($user, $password) == 1);

done_testing;

Then my main script calls the scripts I want as follows:然后我的主脚本调用我想要的脚本如下:

use strict;
use utf8;
use open ':std', ':encoding(UTF-8)';

use TAP::Harness;
use TAP::Formatter::HTML;

my $fmt = TAP::Formatter::HTML->new();
$fmt->output_file( 'foo.html' );

my $test_args = {
  '00_test'    => ['--server', "$server", $debug?'-d':undef, $trace?'-t':undef, '--browser', "firefox"],
  '01_test'    => ['--server', "$server", $debug?'-d':undef, $trace?'-t':undef, '--browser', "chrome"],
};
my $test_output;
my $harness = TAP::Harness->new( {
        test_args => $test_args,
        formatter => $fmt,
        merge => 1
    } );
    
my $result = $harness->runtests( 
    [ 't/00-test.t',    '00_test' ],
    [ 't/01-test.t',    '01_test' ],
);


print "Passed: ". scalar $result->passed . "\n";
print "Failed: ". scalar $result->failed . "\n";

generate_report($result);

This won't work out of the box as I just deleted some lines from my project but gives an idea on how is it able to run the other files and get the results to generate a report, while still being able to run each project individually and also being able to send common parameters to the different tests from the main script.这不会开箱即用,因为我刚刚从我的项目中删除了一些行,但提供了一个关于如何运行其他文件并获取结果以生成报告的想法,同时仍然能够单独运行每个项目并且还能够从主脚本向不同的测试发送通用参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM