狐狸.fox 2009-02-10 18:32 采纳率: 0%
浏览 287
已采纳

Perl build,单元测试,代码覆盖: 一个完整的工作示例

Most Stackoverflow answers that I have found in regards to the Perl build process and unit testing and code coverage simply point me to CPAN for the documentation there. There's absolutely nothing wrong with pointing to CPAN modules because that's where the full documentation is supposed to reside. I've had trouble finding complete working code examples in many cases, though.

I've been searching all over the Internet for actual working code samples that I can download or paste into my IDE, like your typical tutorial "Hello World" example source code, but of an example that demonstrates the build process with unit testing and code coverage analysis. Does anyone have a small example of a complete working project that demonstrates these technologies and processes?

(I do have a small working example and I will answer my own question with it, but there are probably other SO users who have better examples than the ones I came up with.)

转载于:https://stackoverflow.com/questions/533553/perl-build-unit-testing-code-coverage-a-complete-working-example

  • 写回答

5条回答 默认 最新

  • 七度&光 2009-02-10 18:38
    关注

    It took me a while and it also took me taking small snippets from a number of different sources and melting them together, but I think I have a small working example that sufficiently demonstrates to a Perl newbie the Perl build process including unit testing and code coverage analysis & reporting. (I'm using ActiveState ActivePerl v5.10.0 on a Windows XP Pro PC, Module::Build, Test::More, Devel::Cover)

    Start out with a directory for your Perl project and then create a "lib" directory and a "t" directory under your project directory:

    HelloPerlBuildWorld
            |
            |----------> lib
            |
            |----------> t
    

    In the "lib" directory, create a text file named "HelloPerlBuildWorld.pm". This file is your Perl module that you will be building and testing. Paste the following content into this file:

    use strict;
    use warnings;
    package HelloPerlBuildWorld;
    
    $HelloPerlBuildWorld::VERSION = '0.1';
    
    sub hello {
       return "Hello, Perl Build World!";
    }
    
    sub bye {
       return "Goodbye, cruel world!";
    }
    
    sub repeat {
       return 1;
    }
    
    sub argumentTest {
        my ($booleanArg) = @_;
    
        if (!defined($booleanArg)) {
            return "null";
        }
        elsif ($booleanArg eq "false") {
            return "false";
        }
        elsif ($booleanArg eq "true") {
            return "true";
        }
        else {
            return "unknown";
        }
    
       return "Unreachable code: cannot be covered";
    }
    
    1;
    

    In the "t" directory, create a text file named "HelloPerlBuildWorld.t". This file is your unit test script that will attempt to fully test your Perl module above. Paste the following content into this file:

    use strict;
    use warnings;
    use Test::More qw(no_plan);
    
    # Verify module can be included via "use" pragma
    BEGIN { use_ok('HelloPerlBuildWorld') };
    
    # Verify module can be included via "require" pragma
    require_ok( 'HelloPerlBuildWorld' );
    
    # Test hello() routine using a regular expression
    my $helloCall = HelloPerlBuildWorld::hello();
    like($helloCall, qr/Hello, .*World/, "hello() RE test");
    
    # Test hello_message() routine using a got/expected routine
    is($helloCall, "Hello, Perl Build World!", "hello() IS test");
    
    # Do not test bye() routine
    
    # Test repeat() routine using a got/expected routine
    for (my $ctr=1; $ctr<=10; $ctr++) {
        my $repeatCall = HelloPerlBuildWorld::repeat();
        is($repeatCall, 1, "repeat() IS test");
    }
    
    # Test argumentTest() 
    my $argumentTestCall1 = HelloPerlBuildWorld::argumentTest();
    is($argumentTestCall1, "null", "argumentTest() IS null test");
    
    # Test argumentTest("true") 
    my $argumentTestCall2 = HelloPerlBuildWorld::argumentTest("true");
    is($argumentTestCall2, "true", "argumentTest() IS true test");
    
    # Test argumentTest("false") 
    my $argumentTestCall3 = HelloPerlBuildWorld::argumentTest("false");
    is($argumentTestCall3, "false", "argumentTest() IS false test");
    
    # Test argumentTest(123) 
    my $argumentTestCall4 = HelloPerlBuildWorld::argumentTest(123);
    is($argumentTestCall4, "unknown", "argumentTest() IS unknown test");
    

    Now back up in your top level project directory, create a text file named "Build.PL". This file will create your build scripts that you will use later. Paste the following content into this file:

    use strict;
    use warnings;
    use Module::Build;
    
    my $builder = Module::Build->new(
        module_name         => 'HelloPerlBuildWorld',
        license             => 'perl',
        dist_abstract       => 'HelloPerlBuildWorld short description',
        dist_author         => 'Author Name <email_addy@goes.here>',
        build_requires => {
            'Test::More' => '0.10',
        },
    );
    
    $builder->create_build_script();
    

    That's all the files you need. Now from the command line in the top level project directory, type the following command:

    perl Build.PL
    

    You will see something similar to the following:

    Checking prerequisites...
    Looks good
    
    Creating new 'Build' script for 'HelloPerlBuildWorld' version '0.1'
    

    Now you should be able to run your unit tests with the following command:

    Build test
    

    And see something similar to this:

    Copying lib\HelloPerlBuildWorld.pm -> blib\lib\HelloPerlBuildWorld.pm
    t\HelloPerlBuildWorld....ok
    All tests successful.
    Files=1, Tests=18,  0 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU)
    

    To run your unit tests with code coverage analysis, try this:

    Build testcover
    

    And you'll see something on the order of this:

    t\HelloPerlBuildWorld....ok
    All tests successful.
    Files=1, Tests=18, 12 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU)
    cover
    Reading database from D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db
    
    
    ----------------------------------- ------ ------ ------ ------ ------ ------
    File                                  stmt   bran   cond    sub   time  total
    ----------------------------------- ------ ------ ------ ------ ------ ------
    D:/Perl/lib/ActivePerl/Config.pm       0.0    0.0    0.0    0.0    n/a    0.0
    D:/Perl/lib/ActiveState/Path.pm        0.0    0.0    0.0    0.0    n/a    0.0
    D:/Perl/lib/AutoLoader.pm              0.0    0.0    0.0    0.0    n/a    0.0
    D:/Perl/lib/B.pm                      18.6   16.7   13.3   19.2   96.4   17.6
     ...
    [SNIP]
     ...
    D:/Perl/lib/re.pm                      0.0    0.0    0.0    0.0    n/a    0.0
    D:/Perl/lib/strict.pm                 84.6   50.0   50.0  100.0    0.0   73.1
    D:/Perl/lib/vars.pm                   44.4   36.4    0.0  100.0    0.0   36.2
    D:/Perl/lib/warnings.pm               15.3   12.1    0.0   11.1    0.0   12.0
    D:/Perl/lib/warnings/register.pm       0.0    0.0    n/a    0.0    n/a    0.0
    blib/lib/HelloPerlBuildWorld.pm       87.5  100.0    n/a   83.3    0.0   89.3
    Total                                  9.9    4.6    2.8   11.3  100.0    7.6
    ----------------------------------- ------ ------ ------ ------ ------ ------
    
    
    Writing HTML output to D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db/coverage.html ...
    done.
    

    (Someone please tell me how to configure Cover to ignore all the Perl libraries except and just report back to me on my single file that I wrote. I could not get Cover filtering to work according to the CPAN documentation!)

    Now if you refresh your top level directory, you can see a new subdirectory called "cover_db". Go into that directory and double click on the "coverage.html" file to open the code coverage report in your favorite web browser. It gives you a nice color coded hypertext report where you can click on your file name and see detailed statement, branch, condition, subroutine coverage statistics for your Perl module right there in the report next to the actual source code. You can see in this report that we did not cover the "bye()" routine at all and also there is a line of code that is unreachable that was not covered as we expected.

    snapshot of code coverage report http://www.leucht.com/images/CodeCoverageExample.jpg

    One more thing you can do to help automate this process in your IDE is to make some more "Build.PL" type files that explicitly perform some of the build targets that we did above manually from the command line. For example, I use a "BuildTest.PL" file with the following content:

    use strict;
    use warnings;
    use Module::Build;
    
    my $build = Module::Build->resume (
      properties => {
        config_dir => '_build',
      },
    );
    
    $build->dispatch('build');
    $build->dispatch('test');
    

    Then I set up my IDE to execute this file (via "perl BuiltTest.PL") with a single mouse click and it automatically runs my unit test code from the IDE instead of me doing it manually from the command line. Replace the "dispatch('test')" with "dispatch('testcover')" for automated code coverage execution. Type "Build help" for a complete list of build targets that are available from Module::Build.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大