我正在编写一个具有处理文本文件的函数的模块。我刚接触测试,所以我决定选择Test::More
。以下是我的测试文件现在的样子:
use mymod;
use 5.10.0;
use strict;
use warnings;
use Test::More 'no_plan';
my $file_name = "test.file";
sub set_up {
my $self = shift;
open(my $handle,">",$file_name) or die "could not create file test.file $!\n";
# generate a sample text file here
close($handle);
}
sub tear_down {
my $self = shift;
unlink($file_name) or die "could not delete $file_name $!\n";
}
set_up();
open(my $handle,$file_name) || die "could not open $file_name $!\n";
my @lines = mymod->perform($handle);
is_deeply(\@lines,["expected line","another expected line"]);
close($handle);
tear_down();
这是进行测试的好方法吗?在我的测试中处理生成样本输入文件是否可以?
顺便说一下,我开始将其作为Test::Unit
测试编写,然后切换到Test::More
。这就是set_up
和tear_down
函数存在的原因。
答案 0 :(得分:8)
您可以将字符串“打开”为文件句柄,因此您仍然可以为方法提供文件句柄,但不必创建物理文件。这样你就可以将你的测试内容放在一个字符串中(理想情况下是一个字符串数组,每个数据样本一个用于测试),而不必创建临时文件:
my @testdata = (
"test data 1",
"test data 2",
# ...
);
foreach my $data (@testdata)
{
open my $datahandle, "<", \$data or die "Cannot open handle to string: $!";
my @lines = mymod->perform($datahandle);
# ...
}
答案 1 :(得分:5)
使用Test :: More的'no_plan'选项使测试不太可靠:你无法真正知道你是否因为某些原因错过了测试。最好计划预定义数量的测试,或者如果不可能,您可以使用done_testing函数(但需要最新版本的Test :: More)。
ETA:我没有看到你使用open-close-open-close-unlink的事情。我认为你可以更好地打开一个临时文件,填写它并将其用于测试。
答案 2 :(得分:2)
除了使用已经注释的no_plan:
关于在单元测试期间要读取的文件的生成,这可以被认为是可接受的,尽管通常优选avoid touching the files in the unit tests(或任何其他“慢”资源),因为这会减慢测试速度。
如果很多单元测试读取或写入文件以及测试数量增长太多,这可能会成为问题。实际上,单元测试应该是不引人注目的并且快速运行。
如果单元测试的执行时间开始成为问题,您可以提取访问文件系统的测试并将它们添加到运行频率较低的集成测试套件中,或者您可以将代码修改为单独的读取文件及其内容的处理。这样,您可以独立于文件读取测试内容的处理,并将数据存储在单元测试代码中的行数组中。
这种代码往往更容易重复使用,因为您今天在文件中读取的内容可能来自其他来源(例如网络,数据库)。