12

您会推荐哪些框架和工具用于 Perl 中的单元测试和模拟对象?

我有一个现有的 Perl 应用程序,主要执行数据库访问、读取和写入文件。该应用程序基本上是一个批处理作业类型的应用程序,它从文件和数据库中读取一堆东西,并将一堆新文件和一些东西写入数据库。

该应用程序当前没有任何单元测试,但我希望重构应用程序以进行良好的单元测试。

对于单元测试和模拟对象,您会推荐哪些框架和工具?例如类似于Java的HamcrestJMock的东西?

另外,是否有任何好的基于 BDD(行为驱动开发)的 Perl 测试框架?

4

4 回答 4

12

在测试框架方面,我喜欢使用Test::Class,它可以让您以类似于 JUnit 的方式设置好的单元测试层次结构。链接的文档提供了很好的概述,但如果您还不熟悉 Perl 测试约定,请查看Test::SimpleTAP的文档,这是 Perl 测试的标准输出格式。

对于模拟,有Test::Mock::Class,它对于为您直接控制之外的库设置模拟类很有用,例如您的应用程序所依赖的 CPAN 模块。

还有出色的Test::MockDBI,它提供了用于模拟数据库内容的特殊工具。

于 2009-10-05T09:53:50.793 回答
7

只是添加一点关于 BDD 的信息,因为我认为friedo 的答案涵盖了其他所有内容。

快速浏览一下这个 Perlmonks 讨论行为驱动开发:perl 的建议工具?

我认为一些工具可能会为您指明正确的方向:

另请参阅这个 SO 问题:你能回顾一下我对 Cucumber 的 Perl 重写吗?

希望有些帮助。

/I3az/

于 2009-10-05T10:12:35.563 回答
6

最近,使用MooseX::Declare,我一直在使用“真实对象”作为模拟对象。

假设您有一个执行如下接口的数据库驱动程序:

role Database {
    requires 'connect';
    requires 'query';
};

然后你有这样的代码使用数据库:

class FooPage {
    has 'database' => (
        is       => 'ro',
        does     => 'Database',
        required => 1,
    );

    method get_foo() {
        $self->database->query({ foo => 42 });
    }

    method render_page(Str $user) {
        "Hello, $user.  Here is a foo for you: ". $self->get_foo;
    }
};

现在你想测试一下:

use Test::More tests => 2;
use MooseX::Declare;

my $fake_database = class with Database {
    has 'data' => ( is => 'ro', isa => 'HashRef' );
    has 'connected' => ( is => 'rw', isa => 'Bool' );

    method connect() { $self->connected(1) }
    method query(HashRef $query) { $self->data->{$query->{foo}} }
};

my $test_database = $fake_database->name->new(
    data => {
        42 => 'OH HAI',
    },
};

my $foo_page = FooPage->new( database => $test_database );
is $foo_page->get_foo, 'OH HAI', 'got correct foo';
is $foo_page->render_page('jrockway'),
   'Hello, jrockway.  Here is a foo for you: OH HAI',
 'got rendered page';

请注意您的语法是如何简洁的,但是作为您的模拟对象的“真实” Moose 类的全部功能。方便,无限灵活。

(这些只是例子......它也可能更好。)

于 2009-10-05T10:55:24.747 回答
4

它不是一个框架,但最好的测试书籍之一是优秀的Perl Testing: A Developer's Notebook,其中还提供了 Perl 测试框架的建议,例如Test::More.

于 2009-10-05T09:44:01.000 回答