加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl单元测试 – 子程序是否可测试?

发布时间:2020-12-15 21:57:47 所属栏目:大数据 来源:网络整理
导读:我一直在阅读和探索Perl中单元测试和测试驱动开发的概念.我正在研究如何将测试概念融入我的开发中.假设我在这里有一个Perl子程序: sub perforce_filelist { my ($date) = @_; my $path = "//depot/project/design/...module.sv"; my $p4cmd = "p4 files -e
我一直在阅读和探索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;
    }
}

子例程执行Perforce命令并将该命令的输出(这是文件列表)存储到@filelist数组中.这个子程序可以测试吗?测试返回的@filelist是否为空有用吗?我试图教自己如何像单位测试开发人员一样思考.

解决方法

有一些事情使得测试perforce_filelist子例程比它需要的更难:

> p4路径是硬编码的
> p4命令在子例程中构造
> p4命令是固定的(因此,它始终是路径中的第一个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" }

但是,您还必须判断这种分解水平是否值得.对于不经常使用的个人工具,可能工作量太大.对于你必须支持并且很多人使用的东西,它可能是值得的.在这种情况下,您可能需要official P4Perl API.这些价值判断取决于您.但是,在分解问题后,进行更大的更改(例如使用P4Perl)不应该像地震一样.

作为旁注而不是我推荐的这个问题,这是& amp;的用例.并没有参数列表.在这个“加密上下文”中,子程序的参数列表是调用它的子程序的@_.

这些调用继续在链中传递相同的参数,这很难输入和维护:

my @new_files = perforce_filelist( $path,$date );
    my @filelist = get_p4_files( $path,$date ); 
    my $command = make_p4_files_command( $path,$date );

随着&并且没有参数列表(不是偶数()),它将@_传递到下一个级别:

my @new_files = perforce_filelist( $path,$date );

    my @filelist = &get_p4_files; 
    my $command = &make_p4_files_command;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读