Jon*_*n J 7 tdd perl unit-testing subroutine
我一直在阅读和探索Perl中单元测试和测试驱动开发的概念.我正在研究如何将测试概念融入我的开发中.说我在这里有一个Perl子程序:
sub perforce_filelist {
my ($date) = @_;
my $path = "//depot/project/design/...module.sv";
my $p4cmd = "p4 files -e $path\@$date,\@now";
my @filelist = `$p4cmd`;
if (@filelist) {
chomp @filelist;
return @filelist;
}
else {
print "No new files!"
exit 1;
}
}
Run Code Online (Sandbox Code Playgroud)
子例程执行Perforce命令并将该命令的输出(文件列表)存储到@filelist数组中.这个子程序可以测试吗?测试返回@filelist的空是否有用?我正在努力教自己如何像单位测试开发人员那样思考.
有几件事情使得测试perforce_filelist子程序比它需要的更困难:
p4是路径中的第一个)但是,您的子程序的职责是获取文件列表并将其返回.除此之外你做的任何事情都会让你更难测试.如果由于你无法控制它而无法改变它,你可以在将来编写这样的东西:
#!perl -T
# Now perforce_filelist doesn't have responsibility for
# application logic unrelated to the file list
my @new_files = perforce_filelist( $path, $date );
unless( @new_files ) {
print "No new files!"; # but also maybe "Illegal command", etc
exit 1;
}
# Now it's much simpler to see if it's doing it's job, and
# people can make their own decisions about what to do with
# no new files.
sub perforce_filelist {
my ($path, $date) = @_;
my @filelist = get_p4_files( $path, $date );
}
# Inside testing, you can mock this part to simulate
# both returning a list and returning nothing. You
# get to do this without actually running perforce.
#
# You can also test this part separately from everything
# else (so, not printing or exiting)
sub get_p4_files {
my ($path, $date) = @_;
my $command = make_p4_files_command( $path, $date );
return unless defined $command; # perhaps with some logging
my @files = `$command`;
chomp @files;
return @files;
}
# This is where you can scrub input data to untaint values that might
# not be right. You don't want to pass just anything to the shell.
sub make_p4_files_command {
my ($path, $date) = @_;
return unless ...; # validate $path and $date, perhaps with logging
p4() . " files -e $path\@$date,\@now";
}
# Inside testing, you can set a different command to fake
# output. If you are confident the p4 is working correctly,
# you can assume it is and simulate output with your own
# command. That way you don't hit a production resource.
sub p4 { $ENV{"PERFORCE_COMMAND"} // "p4" }
Run Code Online (Sandbox Code Playgroud)
但是,您还必须判断这种分解水平是否值得.对于不经常使用的个人工具,可能工作量太大.对于你必须支持并且很多人使用的东西,它可能是值得的.在这种情况下,您可能需要官方的P4Perl API.那些价值判断取决于你.但是,在分解问题之后,做出更大的改变(例如使用P4Perl)不应该像地震一样.
作为旁注而不是我推荐的这个问题,这是&和没有参数列表的用例.在这个"加密上下文"中,子例程的参数列表是@_调用它的子例程.
这些调用继续传递链中的相同参数,这很难输入和维护:
my @new_files = perforce_filelist( $path, $date );
my @filelist = get_p4_files( $path, $date );
my $command = make_p4_files_command( $path, $date );
Run Code Online (Sandbox Code Playgroud)
使用&和无参数列表(不是偶数()),它传递@_到下一级别:
my @new_files = perforce_filelist( $path, $date );
my @filelist = &get_p4_files;
my $command = &make_p4_files_command;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
571 次 |
| 最近记录: |