我一直在尝试使用Perl实用程序/模块"证明"作为一些单元测试的测试工具.单元测试比"单元"更加"系统",因为我需要将一些后台进程分解为测试的一部分,使用以下...
sub SpinupMonitor{
my $base_dir = shift;
my $config = shift;
my $pid = fork();
if($pid){
return $pid;
}else{
my $cmd = "$base_dir\/..\/bin\/monitor_real.pl -config $config -test";
close STDOUT;
exec ($cmd) or die "cannot exec test code [$cmd]\n";
}
}
sub KillMonitor{
my $pid = shift;
print "Killing monitor [$pid]\n";
kill(1,$pid);
}
Run Code Online (Sandbox Code Playgroud)
但是出于某种原因,当我让我的.t文件启动一些额外的进程时,它会导致测试工具在所有测试完成后挂在第一个.t文件的末尾,而不是转到下一个文件,或者退出如果只有一个.
起初我想知道是否可能是因为我正在杀死我的子流程并让它们不复存在.所以我补充说..
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $pid = wait;
$SIG{CHLD} = \&REAPER;
}
Run Code Online (Sandbox Code Playgroud)
到代码.但这没有用.事实上,在封闭式检查中,我发现我的perl测试文件已经退出并且现在已经不存在了,并且它是证明包装器脚本没有收到它的孩子.事实上,当我在测试脚本的末尾添加了一个die()调用时,我得到了......
# Looks like your test died just after 7.
Run Code Online (Sandbox Code Playgroud)
所以我的脚本退出了,但由于某种原因,线束没有解开.
我确实确认我的子流程肯定是令我感到不安的,因为我在禁用它们的同时测试失败,线束正确退出.
我在启动可能以某种方式扰乱线束的过程的方式有什么问题吗? …
作为Linux 3中用Python 3 [.4-.6] 编写的测试套件的一部分,我必须运行一些第三方测试.第三方测试是bash脚本.它们旨在与Perl的prove
TAP线束一起运行.一个bash脚本最多可以包含几千个单独的测试 - 其中一些可以无限期挂起.超时后,我想杀死测试脚本并收集有关它被卡住的地方的一些信息.
因为bash脚本创建了自己的进程,所以我尝试将整个prove
进程树隔离到一个新的进程组中,因此如果出现问题,我最终可能会整个进程组被杀死.因为测试必须以root权限运行,所以我用它sudo -b
来创建具有root权限的新进程组.这个策略(而不setsid
是以某种方式使用)是我在SE Unix和Linux上收到的关于这个问题的评论的结果.
问题是,prove
如果我sudo -b
通过Python 启动"过早地"杀死它,我会从TAP线束中丢失所有输出subprocess.Popen
.
我把它分成了一个简单的测试用例.以下是一个名为的bash测试脚本job.t
:
#!/bin/bash
MAXCOUNT=20
echo "1..$MAXCOUNT"
for (( i=1; i<=$MAXCOUNT; i++ ))
do
echo "ok $i"
sleep 1
done
Run Code Online (Sandbox Code Playgroud)
仅仅为了比较,我还写了一个Python脚本,命名job.py
产生或多或少相同的输出并表现出相同的行为:
import sys
import time
if __name__ == '__main__':
maxcount = 20
print('1..%d' % maxcount)
for i in range(1, maxcount + 1):
sys.stdout.write('ok %d\n' …
Run Code Online (Sandbox Code Playgroud) 在编写测试时,将在测试文件夹中读取文本文件,但不在该文件夹外部读取文本文件(即,在运行证明6时)。例如,以下代码在测试文件夹中读取ReadConfig.ini,但不在其外部读取:
my %v = ReadIni( 'ReadConfig.ini' );
Run Code Online (Sandbox Code Playgroud)
另一方面,此代码在test文件夹之外起作用:
my %v = ReadIni( $*PROGRAM.dirname.IO.add('ReadConfig.ini') );
Run Code Online (Sandbox Code Playgroud)
正确的语法是什么?
谢谢!
目前我这样运行prove
:
prove -v -r .
Run Code Online (Sandbox Code Playgroud)
有没有办法使用正则表达式排除文件?我无法看到它perldoc prove
或输出prove -H
.
最近,新的伟大事物出现在Perl世界中.在库包中很长一段时间都有t
包含测试的文件夹.现在还有一个xt
包含作者测试的文件夹.在xt
不需要库安装过程中的测试,但它可以帮助图书馆作者日期,以确保该代码是巨大的.
有一个prove
与Perl一起运行测试的spript .如果prove
没有参数运行
,将执行文件夹't'中的所有测试.如果你想同时运行t
并xt
测试你应该写:
prove xt t
Run Code Online (Sandbox Code Playgroud)
它可以向配置文件.proverc
文件添加参数(xt t
).然后,当您在prove
没有参数的情况下运行时,它们将从文件中获取,并且将执行两个文件夹中的测试.
但问题来了.如果你xt t
的.proverc
文件中有文件,你不能只将文件名作为参数传递给prove
.如果你说
prove t/00-load.t
它将执行两个文件夹中的所有测试,因为它从配置文件中获取参数.你需要写prove --norc
t/00-load.t
.但这看起来很难看.
你如何运行xt
测试?
我尝试在调试器下运行测试:
perl -d $(which prove) t/file.t
Run Code Online (Sandbox Code Playgroud)
但这没有任何效果,因为每个测试都是作为单独的工作运行的.
我找到了--exec
选项,但是当我提供它时,我从.proverc
文件和命令行中丢失了任何选项
prove -Ithis/is/lost --exec 'perl -d' t/file.t
Run Code Online (Sandbox Code Playgroud)
如何prove
使用其他选项运行测试,并且不丢失在.proverc
文件和命令行中提供的选项?
我不想重复自己写道:
prove --exec 'perl -d -Ilib -Ilocal/lib/perl5' t/file.t
Run Code Online (Sandbox Code Playgroud)
虽然-Ilib
并且-Ilocal/lib/perl5
都在.proverc
档案
我正在使用Perl prove
测试实用程序(TAP :: Harness)来测试我的程序.
我需要先在本地计算机上运行相同的测试,然后再在远程计算机上运行.
(测试程序应分别连接到localhost或远程主机)
如何使用prove将参数(test_server)传递给测试?我应该使用环境还是有更好的解决方案?
当我使用该prove
实用程序运行perl测试时,如果测试中的方法包含print
未被换行符终止的语句,则它将失败.
use Test::More tests=>1;
ok(foo(), "calling foo");
sub foo{
print "A";
1;
}
Run Code Online (Sandbox Code Playgroud)
这导致了
Bad plan. You planned 1 tests but ran 0.
Run Code Online (Sandbox Code Playgroud)
如果我附加换行符:print "A\n";
测试通过.
(注意,如果我只是执行测试perl mytest.t
而不是使用prove
它通过任何一种方式).
任何想法为什么会这样,以及如何解决它?
我做了很多谷歌搜索,但无法找到这个问题的答案.当您在测试中运行证明(http://perldoc.perl.org/prove.html)时,您会得到一些如下所示的统计信息:
Files=3, Tests=45, 2 wallclock secs ( 0.03 usr 0.00 sys + 0.50 cusr 0.12 csys = 0.65 CPU)
Run Code Online (Sandbox Code Playgroud)
为usr,sys,cusr,csys和CPU提供的数字是什么意思?
我的测试套件的部分内容依赖于 API URL。有时我想使用另一个 URL 运行测试。有没有办法将此参数传递给prove
,或者我需要编辑定义 API URL 的文件吗?
当我尝试时,我得到以下回溯prove factorial
:
Cannot detect source of 'factorial'! at /usr/share/perl/5.18/TAP/Parser/IteratorFactory.pm line 263.
TAP::Parser::IteratorFactory::detect_source('TAP::Parser::IteratorFactory=HASH(0x2856b08)', 'TAP::Parser::Source=HASH(0x2856bc8)') called at /usr/share/perl/5.18/TAP/Parser/IteratorFactory.pm line 213
TAP::Parser::IteratorFactory::make_iterator('TAP::Parser::IteratorFactory=HASH(0x2856b08)', 'TAP::Parser::Source=HASH(0x2856bc8)') called at /usr/share/perl/5.18/TAP/Parser.pm line 469
TAP::Parser::_initialize('TAP::Parser=HASH(0x28569e8)', 'HASH(0x23d8cb8)') called at /usr/share/perl/5.18/TAP/Object.pm line 58
TAP::Object::new('TAP::Parser', 'HASH(0x23d8cb8)') called at /usr/share/perl/5.18/TAP/Object.pm line 133
TAP::Object::_construct('TAP::Harness=HASH(0x2131db8)', 'TAP::Parser', 'HASH(0x23d8cb8)') called at /usr/share/perl/5.18/TAP/Harness.pm line 779
TAP::Harness::make_parser('TAP::Harness=HASH(0x2131db8)', 'TAP::Parser::Scheduler::Job=HASH(0x28235d0)') called at /usr/share/perl/5.18/TAP/Harness.pm line 578
TAP::Harness::_aggregate_single('TAP::Harness=HASH(0x2131db8)', 'TAP::Parser::Aggregator=HASH(0x2740ae0)', 'TAP::Parser::Scheduler=HASH(0x2823570)') called at /usr/share/perl/5.18/TAP/Harness.pm line 670
TAP::Harness::aggregate_tests('TAP::Harness=HASH(0x2131db8)', 'TAP::Parser::Aggregator=HASH(0x2740ae0)', 'factorial') called at /usr/share/perl/5.18/TAP/Harness.pm line 485
TAP::Harness::__ANON__() called at /usr/share/perl/5.18/TAP/Harness.pm line 498
TAP::Harness::runtests('TAP::Harness=HASH(0x2131db8)', 'factorial') …
Run Code Online (Sandbox Code Playgroud)