Perl构建,单元测试,代码覆盖:完整的工作示例 [英] Perl build, unit testing, code coverage: A complete working example

查看:91
本文介绍了Perl构建,单元测试,代码覆盖:完整的工作示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现的有关Perl构建过程,单元测试和代码覆盖率的大多数Stackoverflow答案只是将我引向CPAN那里的文档.指向CPAN模块绝对没有错,因为应该将完整的文档保存在这里.不过,在很多情况下,我都很难找到完整的工作代码示例.

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.

我一直在Internet上搜索可以下载或粘贴到IDE中的实际工作代码示例,例如典型的教程"Hello World"示例源代码,但该示例演示了使用unit进行构建的过程测试和代码覆盖率分析.有人有一个完整的工作项目的小例子来演示这些技术和过程吗?

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?

(我确实有一个小的工作示例,我将用它回答我自己的问题,但是可能还有其他SO用户拥有比我想出的示例更好的示例.)

推荐答案

我花了一段时间,还花了许多不同来源的小片段并将它们融合在一起,但是我想我有一个小的工作示例足以向Perl新手演示Perl的构建过程,包括单元测试和代码覆盖率分析及测试.报告. (我在Windows XP Pro PC上使用 ActiveState ActivePerl v5.10.0, Module :: Build

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)

从Perl项目的目录开始,然后在项目目录下创建一个"lib"目录和一个"t"目录:

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

在"lib"目录中,创建一个名为"HelloPerlBuildWorld.pm"的文本文件.该文件是您将要构建和测试的Perl模块.将以下内容粘贴到该文件中:

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;

在"t"目录中,创建一个名为"HelloPerlBuildWorld.t"的文本文件.此文件是您的单元测试脚本,它将尝试完全测试上面的Perl模块.将以下内容粘贴到该文件中:

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");

现在,在顶级项目目录中备份,创建一个名为"Build.PL"的文本文件.该文件将创建您的构建脚本,供以后使用.将以下内容粘贴到该文件中:

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

然后看到类似的内容:

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.

(有人请告诉我如何配置Cover以忽略所有Perl库,而仅对我编写的单个文件报告给我.根据CPAN文档,我无法使Cover过滤正常工作! )

现在,如果刷新顶级目录,则可以看到一个名为"cover_db"的新子目录.进入该目录并双击"coverage.html"文件,以在您喜欢的Web浏览器中打开代码覆盖率报告.它为您提供了一个漂亮的彩色编码超文本报告,您可以在其中单击文件名,并在报告的实际源代码旁边直接查看Perl模块的详细语句,分支,条件,子例程覆盖率统计信息.您可以在此报告中看到,我们根本没有涵盖"bye()"例程,并且还有一些无法访问的代码没有如我们预期的那样被覆盖.

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.


(来源:
leucht.com )


(source: leucht.com)

您可以做的另一件事,是帮助在IDE中自动执行此过程,是制作更多的"Build.PL"类型文件,这些文件明确执行我们上面从命令行手动执行的一些构建目标.例如,我使用具有以下内容的"BuildTest.PL"文件:

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');

然后,我通过单击鼠标将IDE设置为执行此文件(通过"perl BuiltTest.PL"),它会自动从IDE运行我的单元测试代码,而不是从命令行手动执行它.将"dispatch('test')"替换为"dispatch('testcover')",以执行自动代码覆盖.键入构建帮助"以获取Module :: Build可用的构建目标的完整列表.

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.

这篇关于Perl构建,单元测试,代码覆盖:完整的工作示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆