<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>idv2 &#187; test</title>
	<atom:link href="http://tech.idv2.com/tag/test/feed/" rel="self" type="application/rss+xml" />
	<link>http://tech.idv2.com</link>
	<description>关注Web开发技术，关注Internet。</description>
	<lastBuildDate>Tue, 27 Jul 2010 12:54:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>如何当好测试组长(1)-制定测试计划</title>
		<link>http://tech.idv2.com/2009/12/08/testleader-01/</link>
		<comments>http://tech.idv2.com/2009/12/08/testleader-01/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 12:09:53 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[管理]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/?p=724</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>每个软件都要进行测试，每个软件公司也都会进行测试，但通常，
测试都被当作最简单、最没有技术含量的工作，搞技术的人不愿意做，
全都交给一群新人。其实测试是软件质量的最后一道关卡，
没有测试，软件的质量很难保证。</p>
<p>测试的过程可以分为计划、分析、设计、实现、执行、报告这几个阶段。
诚然，执行测试的确不需要多少技术，新人经过一两天培训就能上手。
但是，计划、分析、设计、实现、报告等过程，没有几年的软件工作经验，
是不可能完成的。下面先来说说测试计划。</p>
<!-- end Pukiwiki generated code--><span id="more-724"></span><!-- begin Pukiwiki generated code--><p><strong>测试的目的、定义和范围</strong></p>
<p>制定测试计划时，首先必须明确的是测试的目的、定义和范围。</p>
<p>一般来说，测试的目的有三种：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>防止发生bug</li>
<li>找出bug</li>
<li>保证软件质量</li></ul>
<p>找bug的测试用例和保证质量的测试用例是完全不同的。比如，回归测试的目的是防止发生bug，
每次产品发布都应该执行，所以应尽量让测试用例能自动执行，减少测试执行的工作量；
而为了找出bug，就要尽可能全面地考虑各种特殊值、错误处理、安全问题等；
而保证软件质量的测试，则应当模拟完整的业务流程。</p>
<p>至于定义，也许你会觉得，“地球人都知道，有写的必要吗？”你可以去问问你的组员，单元测试、
综合测试和系统测试是什么意思，可能十个人会给出十个答案。在流程完善的大公司里还好些，
小公司里这种现象会很严重。所以有必要把大家对测试的认识统一起来。</p>
<p>范围也是必须明确的因素。测试整个系统，还是特定的模块？在什么硬件、什么操作系统上测试？
这些也都必须事先明确。</p>
<p><strong>测试的读者对象</strong></p>
<p>接下来还要明确，测试计划是给谁看的？可能你会认为是给测试者看的，那么该计划是否需要
给客户看？是否其他项目干系人如上司、公司决策者会关心该计划？测试计划应该根据读者对象，
写出读者最想知道的内容。</p>
<p><strong>测试的环境</strong></p>
<p>接下来就是测试环境了。这恐怕是最复杂的因素了：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>操作系统是XP，Vista，还是Win7？</li>
<li>Linux的话，是RHEL4，5还是CentOS？要不要支持Debian、SuSE等？</li>
<li>浏览器是IE、Firefox还是Opera？IE的话需要测试什么版本？</li>
<li>数据库是MySQL，Oracle还是SQLServer？</li>
<li>硬件配置有什么要求？</li>
<li>网络环境有什么特殊要求（如IP地址、网络拓扑结构、带宽等）？</li>
<li>服务器和客户端各需要架设几台？它们之间如何连接？</li>
<li>安装时使用的序列号是什么？</li></ul>
<p>稍有经验的人就会知道，各种测试环境的组合会让测试数量成倍增长。比如测试网站，操作系统XP + Vista + Win7，
浏览器 IE6 + IE7 + IE8 + Firefox，组合起来就是3 x 4 = 12种环境，原本500项测试用例就会膨胀到6000条。
这显然是不现实的。因此要找出最有效的组合方式，避免测试用例爆炸。</p>
<p>比如这个例子中，我们知道Vista下没有IE6，Win7下没有IE6和IE7，这样就能减少3种环境。
另外，不同操作系统下，只要浏览器相同，表现形式也几乎相同，所以不用测试所有组合情况，
只需测试 XP + IE6、Vista + IE7、Win7 + IE8、Vista + Firefox四种环境即可。
另外，这些都是客户端的测试，假如500个用例中有200项是服务器端的测试，
那么这200项只需在一个环境中测试即可。这样最后的测试数量是 300 x 4 + 200 = 1400，
比最初的6000项要少了许多。</p>
<p><strong>测试组的编制和日程</strong></p>
<p>此外，测试组的编制和日程计划也必须在计划中明确。谁负责写测试用例，谁负责执行测试，谁负责报告？
现有的成员能否在规定的时间内完成？测试人员的能力是否达到要求？</p>
<p>编制通常用组织结构图来表现：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/12/testleader-01-01.png" alt="testleader-01-01.png" title="testleader-01-01.png" width="565" height="253" /></div>

<p>而任务责任分工可以用TRM(Task Responsibility Matrix，也称RAM——Responsibility Assignment Matrix）来表现。
TRM中用行表示任务，列表示各个成员，行列交点处使用圆圈、三角等表示不同的责任。最简单的TRM如：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/12/testleader-01-02.png" alt="testleader-01-02.png" title="testleader-01-02.png" width="456" height="220" /></div>

<p>日程计划可以用甘特图表现，这个就不再附图了。</p>
<!-- end Pukiwiki generated code-->

]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>每个软件都要进行测试，每个软件公司也都会进行测试，但通常，
测试都被当作最简单、最没有技术含量的工作，搞技术的人不愿意做，
全都交给一群新人。其实测试是软件质量的最后一道关卡，
没有测试，软件的质量很难保证。</p>
<p>测试的过程可以分为计划、分析、设计、实现、执行、报告这几个阶段。
诚然，执行测试的确不需要多少技术，新人经过一两天培训就能上手。
但是，计划、分析、设计、实现、报告等过程，没有几年的软件工作经验，
是不可能完成的。下面先来说说测试计划。</p>
<!-- end Pukiwiki generated code--><span id="more-724"></span><!-- begin Pukiwiki generated code--><p><strong>测试的目的、定义和范围</strong></p>
<p>制定测试计划时，首先必须明确的是测试的目的、定义和范围。</p>
<p>一般来说，测试的目的有三种：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>防止发生bug</li>
<li>找出bug</li>
<li>保证软件质量</li></ul>
<p>找bug的测试用例和保证质量的测试用例是完全不同的。比如，回归测试的目的是防止发生bug，
每次产品发布都应该执行，所以应尽量让测试用例能自动执行，减少测试执行的工作量；
而为了找出bug，就要尽可能全面地考虑各种特殊值、错误处理、安全问题等；
而保证软件质量的测试，则应当模拟完整的业务流程。</p>
<p>至于定义，也许你会觉得，“地球人都知道，有写的必要吗？”你可以去问问你的组员，单元测试、
综合测试和系统测试是什么意思，可能十个人会给出十个答案。在流程完善的大公司里还好些，
小公司里这种现象会很严重。所以有必要把大家对测试的认识统一起来。</p>
<p>范围也是必须明确的因素。测试整个系统，还是特定的模块？在什么硬件、什么操作系统上测试？
这些也都必须事先明确。</p>
<p><strong>测试的读者对象</strong></p>
<p>接下来还要明确，测试计划是给谁看的？可能你会认为是给测试者看的，那么该计划是否需要
给客户看？是否其他项目干系人如上司、公司决策者会关心该计划？测试计划应该根据读者对象，
写出读者最想知道的内容。</p>
<p><strong>测试的环境</strong></p>
<p>接下来就是测试环境了。这恐怕是最复杂的因素了：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>操作系统是XP，Vista，还是Win7？</li>
<li>Linux的话，是RHEL4，5还是CentOS？要不要支持Debian、SuSE等？</li>
<li>浏览器是IE、Firefox还是Opera？IE的话需要测试什么版本？</li>
<li>数据库是MySQL，Oracle还是SQLServer？</li>
<li>硬件配置有什么要求？</li>
<li>网络环境有什么特殊要求（如IP地址、网络拓扑结构、带宽等）？</li>
<li>服务器和客户端各需要架设几台？它们之间如何连接？</li>
<li>安装时使用的序列号是什么？</li></ul>
<p>稍有经验的人就会知道，各种测试环境的组合会让测试数量成倍增长。比如测试网站，操作系统XP + Vista + Win7，
浏览器 IE6 + IE7 + IE8 + Firefox，组合起来就是3 x 4 = 12种环境，原本500项测试用例就会膨胀到6000条。
这显然是不现实的。因此要找出最有效的组合方式，避免测试用例爆炸。</p>
<p>比如这个例子中，我们知道Vista下没有IE6，Win7下没有IE6和IE7，这样就能减少3种环境。
另外，不同操作系统下，只要浏览器相同，表现形式也几乎相同，所以不用测试所有组合情况，
只需测试 XP + IE6、Vista + IE7、Win7 + IE8、Vista + Firefox四种环境即可。
另外，这些都是客户端的测试，假如500个用例中有200项是服务器端的测试，
那么这200项只需在一个环境中测试即可。这样最后的测试数量是 300 x 4 + 200 = 1400，
比最初的6000项要少了许多。</p>
<p><strong>测试组的编制和日程</strong></p>
<p>此外，测试组的编制和日程计划也必须在计划中明确。谁负责写测试用例，谁负责执行测试，谁负责报告？
现有的成员能否在规定的时间内完成？测试人员的能力是否达到要求？</p>
<p>编制通常用组织结构图来表现：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/12/testleader-01-01.png" alt="testleader-01-01.png" title="testleader-01-01.png" width="565" height="253" /></div>

<p>而任务责任分工可以用TRM(Task Responsibility Matrix，也称RAM——Responsibility Assignment Matrix）来表现。
TRM中用行表示任务，列表示各个成员，行列交点处使用圆圈、三角等表示不同的责任。最简单的TRM如：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/12/testleader-01-02.png" alt="testleader-01-02.png" title="testleader-01-02.png" width="456" height="220" /></div>

<p>日程计划可以用甘特图表现，这个就不再附图了。</p>
<!-- end Pukiwiki generated code-->

]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/12/08/testleader-01/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Perl]use Test::Base;</title>
		<link>http://tech.idv2.com/2007/10/09/use-test-base/</link>
		<comments>http://tech.idv2.com/2007/10/09/use-test-base/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 14:18:37 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[perl]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2007/10/09/use-test-base/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>Test::Base是什么？用官方的说法是“数据驱动的测试”。Test::Base是一个测试框架，
只要给它提供测试数据，它就能自动进行单元测试，省却了手工编写测试程序的麻烦。</p>
<p>可能有人用过Test::More模块进行自动测试，那么我推荐你使用Test::Base。Test::Base
与Test::More完全兼容，也就是说你可以仅仅将use Test::More;换成use Test::Base;
而不用改动任何其他代码；其次，Test::Base可以提供更为简单的测试方法，
让你不必在繁琐的测试程序上花费时间。</p>
<!-- end Pukiwiki generated code--><span id="more-521"></span><!-- begin Pukiwiki generated code--><p>我们来看一个具体的例子。下面是我们要测试的程序，函数plural接受一个英文单词，
返回它的复数形式。</p>
<pre>package My::Test::English;

# 返回单词的复数
sub plural {

    my $word = shift;

    # 以s/x/sh/ch结尾的情况
    if ( $word =~ /(s|x|sh|ch)$/ ) {
        $word .= 'es';
    }

    # 以辅音+y结尾的情况
    elsif ( $word =~ /[^aeiou]y$/ ) {
        $word =~ s/y$/ies/;
    }

    # 以f结尾的情况
    elsif ( $word =~ /f$/ ) {
        $word =~ s/f$/ves/;
    }

    # 其他情况
    else {
        $word .= 's';
    }

    return $word;
}

1;
</pre>
<p>让我们来看看如何使用Test::Base对这个函数进行测试。
测试程序如下。文件保存为 plural.t，因为测试用例文件的扩展名通常为 .t。</p>
<pre>#!/usr/bin/perl

use My::Test::English;
use Test::Base;

sub plural { My::Test::English::plural(shift) }

run_is 'input' =&gt; 'expected';

__END__

=== plural test 1
--- input chomp plural
leaf
--- expected chomp
leaves

=== plural test 2
--- input chomp plural
goose
--- expected chomp
geese</pre>
<p>该程序执行后结果如下：</p>
<pre>D:\perl&gt;perl plural.t
ok 1 - plural test 1
not ok 2 - plural test 2
#   Failed test 'plural test 2'
#   in plural.t at line 8.
#          got: 'gooses'
#     expected: 'geese'
1..2
# Looks like you failed 1 test of 2.</pre>
<p>可见，未通过的测试用例会很明显地显示出来，省却了用人眼比较的麻烦。</p>
<p>如果你有多个 .t 文件，可以用 prove 命令，它会依次运行每一个 .t，
并给出全体的测试结果。</p>
<pre>D:\perl&gt;prove
.\plural....ok 1/0
.\plural....NOK 2#   Failed test 'plural test 2'
#   in .\plural.t at line 8.
#          got: 'gooses'
#     expected: 'geese'
# Looks like you failed 1 test of 2.
.\plural....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 2
        Failed 1/2 tests, 50.00% okay
Failed Test Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
.\plural.t     1   256     2    1  50.00%  2
Failed 1/1 test scripts, 0.00% okay. 1/2 subtests failed, 50.00% okay.</pre>
<p>让我们来分析一下这段程序。</p>
<p>测试程序开头引用了Test::Base，随后定义了一个名为 plural 的函数，
以调用 My::Test::English::plural。__END__ 标记之后是测试数据，
测试数据的格式如下：</p>
<pre>=== 测试数据标题
--- &lt;输入数据名&gt; [&lt;过滤器1&gt; &lt;过滤器2&gt; ...]
输入数据
--- &lt;预期输出数据名&gt; [&lt;过滤器1&gt; &lt;过滤器2&gt; ...]
预期输出数据</pre>
<p>测试数据标题可以随便写，仅仅是标识一个数据的开始。数据名就是 run_is 函数中
使用的名称，本例中'input'为输入，'expected'为预期输出。</p>
<p>然后要说明的就是过滤器。Test::Base接收的测试数据都是成对的——一个是输入，
一个是预期的输出，而Test::Base会使用输入数据运行被测试函数，
如果得到的输出结果等于预期输出，则判定为ok，否则为fail。</p>
<p>默认情况下，传递给Test::Base的测试数据都是字符串，显然不能满足各种各样测试的要求，
所以Test::Base提供了filter这个概念，可以通过filter将字符串类型的测试数据转换成所需类型，
再进行测试。再进一步，可以将被测试函数也做成一个filter，
这样输入数据和预期输出数据分别通过各自的过滤器后得到的结果应该相等，</p>
<p>上例中，chomp过滤器表示去掉数据末尾的换行，plural则为自定义的plural函数。
所以上例的过滤器的实际意义就是：</p>
<p><strong>input数据去掉换行后，再用plural函数处理，得到的结果应当与expected数据去掉换行的结果相同。</strong></p>
<p>如果输入数据是数组或散列等复杂数据，则可以使用eval过滤器生成：</p>
<pre>=== test
--- input eval testfunc
{ name =&gt; 'google', url =&gt; 'http://www.google.com' }
--- expected chomp
google</pre>
<p>其他的默认过滤器可以参考 perldoc Test::Base::Filter。</p>
<p>这就是Test::Base的实质，通过过滤器来生成数据、执行被测试函数，
最后与预期结果比较。</p>
<p>上面的程序还可以更简单些。首先，用 filters 可以定义输入数据和预期输出数据的默认过滤器，
而不必将过滤器写在每个测试数据上：</p>
<pre>filters { 'input' =&gt; [ 'chomp', 'plural' ], 'expected' =&gt; 'chomp' };
sub plural { My::Test::English::plural(shift) }

__END__

=== plural test 1
--- input
leaf
--- expected
leaves

=== plural test 2
--- input
goose
--- expected
geese
</pre>
<p>其次，run_is动作可以省略，Test::Base会自动查找测试数据。
（实际上省略run_is后的默认动作为run_compare，与run_is很相似，有兴趣的可以参考 perldoc Test::Base。）</p>
<p>这样最终的测试程序如下：</p>
<pre>#!/usr/bin/perl

use My::Test::English;
use Test::Base;

filters { 'input' =&gt; [ 'chomp', 'plural' ], 'expected' =&gt; 'chomp' };
sub plural { My::Test::English::plural(shift) }

__END__

=== plural test 1
--- input
leaf
--- expected
leaves

=== plural test 2
--- input
goose
--- expected
geese
</pre>
<!-- end Pukiwiki generated code-->
]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>Test::Base是什么？用官方的说法是“数据驱动的测试”。Test::Base是一个测试框架，
只要给它提供测试数据，它就能自动进行单元测试，省却了手工编写测试程序的麻烦。</p>
<p>可能有人用过Test::More模块进行自动测试，那么我推荐你使用Test::Base。Test::Base
与Test::More完全兼容，也就是说你可以仅仅将use Test::More;换成use Test::Base;
而不用改动任何其他代码；其次，Test::Base可以提供更为简单的测试方法，
让你不必在繁琐的测试程序上花费时间。</p>
<!-- end Pukiwiki generated code--><span id="more-521"></span><!-- begin Pukiwiki generated code--><p>我们来看一个具体的例子。下面是我们要测试的程序，函数plural接受一个英文单词，
返回它的复数形式。</p>
<pre>package My::Test::English;

# 返回单词的复数
sub plural {

    my $word = shift;

    # 以s/x/sh/ch结尾的情况
    if ( $word =~ /(s|x|sh|ch)$/ ) {
        $word .= 'es';
    }

    # 以辅音+y结尾的情况
    elsif ( $word =~ /[^aeiou]y$/ ) {
        $word =~ s/y$/ies/;
    }

    # 以f结尾的情况
    elsif ( $word =~ /f$/ ) {
        $word =~ s/f$/ves/;
    }

    # 其他情况
    else {
        $word .= 's';
    }

    return $word;
}

1;
</pre>
<p>让我们来看看如何使用Test::Base对这个函数进行测试。
测试程序如下。文件保存为 plural.t，因为测试用例文件的扩展名通常为 .t。</p>
<pre>#!/usr/bin/perl

use My::Test::English;
use Test::Base;

sub plural { My::Test::English::plural(shift) }

run_is 'input' =&gt; 'expected';

__END__

=== plural test 1
--- input chomp plural
leaf
--- expected chomp
leaves

=== plural test 2
--- input chomp plural
goose
--- expected chomp
geese</pre>
<p>该程序执行后结果如下：</p>
<pre>D:\perl&gt;perl plural.t
ok 1 - plural test 1
not ok 2 - plural test 2
#   Failed test 'plural test 2'
#   in plural.t at line 8.
#          got: 'gooses'
#     expected: 'geese'
1..2
# Looks like you failed 1 test of 2.</pre>
<p>可见，未通过的测试用例会很明显地显示出来，省却了用人眼比较的麻烦。</p>
<p>如果你有多个 .t 文件，可以用 prove 命令，它会依次运行每一个 .t，
并给出全体的测试结果。</p>
<pre>D:\perl&gt;prove
.\plural....ok 1/0
.\plural....NOK 2#   Failed test 'plural test 2'
#   in .\plural.t at line 8.
#          got: 'gooses'
#     expected: 'geese'
# Looks like you failed 1 test of 2.
.\plural....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 2
        Failed 1/2 tests, 50.00% okay
Failed Test Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
.\plural.t     1   256     2    1  50.00%  2
Failed 1/1 test scripts, 0.00% okay. 1/2 subtests failed, 50.00% okay.</pre>
<p>让我们来分析一下这段程序。</p>
<p>测试程序开头引用了Test::Base，随后定义了一个名为 plural 的函数，
以调用 My::Test::English::plural。__END__ 标记之后是测试数据，
测试数据的格式如下：</p>
<pre>=== 测试数据标题
--- &lt;输入数据名&gt; [&lt;过滤器1&gt; &lt;过滤器2&gt; ...]
输入数据
--- &lt;预期输出数据名&gt; [&lt;过滤器1&gt; &lt;过滤器2&gt; ...]
预期输出数据</pre>
<p>测试数据标题可以随便写，仅仅是标识一个数据的开始。数据名就是 run_is 函数中
使用的名称，本例中'input'为输入，'expected'为预期输出。</p>
<p>然后要说明的就是过滤器。Test::Base接收的测试数据都是成对的——一个是输入，
一个是预期的输出，而Test::Base会使用输入数据运行被测试函数，
如果得到的输出结果等于预期输出，则判定为ok，否则为fail。</p>
<p>默认情况下，传递给Test::Base的测试数据都是字符串，显然不能满足各种各样测试的要求，
所以Test::Base提供了filter这个概念，可以通过filter将字符串类型的测试数据转换成所需类型，
再进行测试。再进一步，可以将被测试函数也做成一个filter，
这样输入数据和预期输出数据分别通过各自的过滤器后得到的结果应该相等，</p>
<p>上例中，chomp过滤器表示去掉数据末尾的换行，plural则为自定义的plural函数。
所以上例的过滤器的实际意义就是：</p>
<p><strong>input数据去掉换行后，再用plural函数处理，得到的结果应当与expected数据去掉换行的结果相同。</strong></p>
<p>如果输入数据是数组或散列等复杂数据，则可以使用eval过滤器生成：</p>
<pre>=== test
--- input eval testfunc
{ name =&gt; 'google', url =&gt; 'http://www.google.com' }
--- expected chomp
google</pre>
<p>其他的默认过滤器可以参考 perldoc Test::Base::Filter。</p>
<p>这就是Test::Base的实质，通过过滤器来生成数据、执行被测试函数，
最后与预期结果比较。</p>
<p>上面的程序还可以更简单些。首先，用 filters 可以定义输入数据和预期输出数据的默认过滤器，
而不必将过滤器写在每个测试数据上：</p>
<pre>filters { 'input' =&gt; [ 'chomp', 'plural' ], 'expected' =&gt; 'chomp' };
sub plural { My::Test::English::plural(shift) }

__END__

=== plural test 1
--- input
leaf
--- expected
leaves

=== plural test 2
--- input
goose
--- expected
geese
</pre>
<p>其次，run_is动作可以省略，Test::Base会自动查找测试数据。
（实际上省略run_is后的默认动作为run_compare，与run_is很相似，有兴趣的可以参考 perldoc Test::Base。）</p>
<p>这样最终的测试程序如下：</p>
<pre>#!/usr/bin/perl

use My::Test::English;
use Test::Base;

filters { 'input' =&gt; [ 'chomp', 'plural' ], 'expected' =&gt; 'chomp' };
sub plural { My::Test::English::plural(shift) }

__END__

=== plural test 1
--- input
leaf
--- expected
leaves

=== plural test 2
--- input
goose
--- expected
geese
</pre>
<!-- end Pukiwiki generated code-->
]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2007/10/09/use-test-base/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
