Posted on 20-12-2012
Filed Under (技术) by waterlin

又发现一个 Perl 在 Windows 下的发行版,Indigoperl

好像还不错,安装包也方便,简单几行命令就搞定了:

(0) Comments    Read More   
Posted on 30-09-2010
Filed Under (技术) by waterlin

苦于没有空闲的 Linux 服务器了,只好用 Windows 来搭一个 Bugzilla 服务器。浏忙绪绪我今天就给大家介绍一下 Windows 下 Bugzilla 的简易安装与配置。

一次性简易安装 Bugzilla

Windows 下安装 Bugzilla 可以看官方文档,不过这里推荐使用一次性简易完全安装包,懒人有懒福嘛。的确,对于小公司来说,没有什么需要精心配置的东西。

配置 SendMail 的替代品

Bugzilla 如果不能发邮件通知更新,那查找 bug 的最新状况,将是非常痛苦的一件事情。

但是 Bugzilla 默认下用 SMTP 的话,不能带 SMTP TLS 校验的东西,可以通过安装 Perl 包 Email::Send::SMTP 来解决这个问题。

不过,在这里,我更推荐用伪装 SendMail 的方法来解决这个问题。

在 Windows 下,有一个很简单的方法来伪装 SendMail 发邮件的方式,它实际上还是使用 SMTP 的方式。

如果你的 Bugzilla 安装在 D:\Bugzilla ,则你把假 SendMail 解压放到目录 D:\usr\lib 里即可,注意驱动器要相同。

配置好了以后,记得从命令行测试一下假的 SendMail 配置是否正确:

上面这个例子,就是提示配置不正确。

这样,就可以用 Gmail 来发提醒邮件了。不过要注意,如果要配置用 Gmail 来发邮件,要在 Bugzilla 的管理面板里有关邮件的设置里,把 smtpserver 设置为 smtp.gmail.com:587 即可。

简单设置 Bugzilla

记得,要设置 urlbase,否则用户一注册,收到的邮件里,都没有网址的前缀了 :)

后续话题

以后再介绍更多小技巧,呵,敬请期待。

(0) Comments    Read More   
Posted on 25-09-2009
Filed Under (技术) by waterlin

补充一下昨天总结的查询本地已经安装了哪些 Perl 模块的方法,还有两种方法可以用:

  1. 在 shell 里运行下面的语句:

    如果提示了类似下面的错误, Can’t locate Smart/Comments.pm in @INC (@INC contains: c:/strawberry/perl/lib c:/strawberry/perl/site/lib .).

    则表明你的 Perl 并没有安装这个模块。如果已经安装了该模块,则不会发生任何事情。

    还可以用相类似的方法来测试,比如说,直接从 shell 里运行一下 Perl 的 use 命令:

    直接在后面使用 use 语句,如果这个模块存在的话,则不会报错;如果这个模块不存在的话,会提示出错信息。

  2. 如果在 Perl 代码里需要查询、获得已安装的模块信息,则可以使用 ExtUtils::Installed 模块。
(0) Comments    Read More   
Posted on 24-09-2009
Filed Under (技术) by waterlin

要查询本地已经安装了哪些 Perl 模块 (module),我们可以用命令

来查询,这个命令会显示出你系统里所有已经安装上的模块名称、安装路径等信息。

同样,如果是 ActivePerl,可以用命令

来检查已安装的模块信息。

(0) Comments    Read More   
Posted on 23-09-2009
Filed Under (技术) by waterlin

最近用 Perl 写了不少自动化测试工具,用到了一些模块,有几个觉得挺好的,记录下来,以后说不定还有需要用到呢。

  1. Smart::Comments

    Smart comments 提供了一个调试与追踪代码的简单方法,可以打印一个变量值,也可以追踪、显示一个循环的进度等。

    最巧妙的是,当你完成了程序的编写,不需要这些调试代码的时候,只需要注释掉

    这行就可以了。下次还需要再次调试代码的时候,不需要再添加一遍追踪代码,只要把上面那行代码重新激活就可以了。

    如果你不在程序里用上面的语句显式的激活 smart comments,我们也可以在运行脚本的时候,显示地激活 smart comments 模块:

  2. 给 Perl 提供类似 C++ 宏的功能

    如果有一段代码,需要在多个地方重复用到,但是写成函数却并不是很合适,这个时候,最好的办法,是用类似于 C++ 的宏定义,在需要的地方插入这个宏即可。可以用 Filter::cpp 这个模块来实现,安装这个模块后,用起来和 C++ 的宏就没有什么区别了。

  3. 在 Perl 里操作 Excel 文件

    现在很多测试用的测试用例 (test case) 以及测试报告都是用 Excel 来写的,要完成自动化测试,Perl 脚本最好能够自动从 Excel 读入数据、并在相应位置上记录测试结果。与这相关的工作,可以用下面的模块来完成:

    如果我们需要读入 (parse) 一个已有的 Excel 文件,可以使用 Spreadsheet::ParseExcel,适用于 Excel 95-2003 版本。如果你用的是 Excel 2007 版本,则你需要用 Spreadsheet::XLSX 这个模块。

    如果我们需要创建一个全新的 Excel 文件并写入数据,我们可以用 Spreadsheet::WriteExcel 模块。

    如果我们需要打开一个 Excel 文件读入测试数据、再输出测试数据到这个 Excel 文件,我们需要使用 Spreadsheet::ParseExcel::SaveParser 这个模块,它综合了 Spreadsheet::ParseExcel 和 Spreadsheet::WriteExcel 的功能。这里特别强调一下,不管是修改 (overwrite) 已有的 Excel 数据,还是创建 (add) 新的 Excel 数据,均可以使用 AddCell 这个方法,如下所示:

    最重要的是,在用 AddCell 修改或是添加了新数据后,一定要记得保存 Excel 文件,否则修改不会被保存下来!保存文件用下面的语句:

    如果是同一个文件名,则把数据保存到原来的文件;如果是新文件名,则把数据保存到新的文件里。

  4. Badger::Timestamp

    Badger::Timestamp 模块可以很方便地对时间戳 (timestamp) 进行修改、比较等操作,相当方便。

(1) Comment    Read More   
Posted on 21-09-2009
Filed Under (技术) by waterlin

假如我有一个子过程,定义如下:

我又有一个变量:

这个 $test 的值刚好就是上面子过程的名称。既然我通过 $test 知道了这个子过程名称,我可以通过 $test 达到调用这个子过程的目的吗?也就是说,我让用户从命令行里输入一个子过程的名称,然后就可以根据这个名称来调用相对应的子过程。

方法一,直接根据用户输入的子过程名来调用该子过程。

完整的例子代码如下:

这里要注意,需要用

这个语句,否则脚本不能运行,Perl 解释器会提示类似于下面的错误:

Global symbol “$test” requires explicit package name at test2.pl line 10.

方法二,更常规的做法是专门用一个起分派作用的散列,根据用户输入的请示而调用相应的子过程。例如下面的 %dispatcher 就起到了绑定识别标记与相应子过程引用的作用,通过这个唯一的标记 (key),我们可以很容易地找到对应的子过程引用

然后可以用和方法一相同的语法来调用这个子过程:

下面是方法二的一个完整的例子:

当然,方法二要比方法一优秀得多,它可以避免用户输入错误的子过程名而导致一系列的麻烦。

(0) Comments    Read More   
Posted on 13-08-2009
Filed Under (技术) by waterlin

今天碰巧用到,觉得挺有用的:

1) 用Perl获得当前目录的路径名:

use Cwd;
print getcwd;

2) 打印变量值到屏幕的同时,保存到一个变量里:

print $str = ‘foo bar’;

当然,换成文件句柄也是一样的。

(2) Comments    Read More   
Posted on 08-05-2009
Filed Under (技术) by waterlin

最近在用Perl来做工作的时候,运行到一个地方,需要我输入一个设备名,以判断接下来应该做的步骤。每次运行到这里,我都是手动输入很长的设备名,比如说ciscocontenteng,每次这样输入,不仅累死人,还很容易出错。

这种情况下,可以用Term::Complete这个module来实现用tab键自动补全。用法非常简单,看代码就差不多能理解了:

use warnings;
use strict;

use Term::Complete;

my @completion_list = (“atest”,”btest”,”cdtest”,”efgtest”);

my $input = Complete(‘please input the start character and use tab to complete: ‘, \@completion_list);
#$input = Complete(‘prompt_string’, @completion_list);

print “The input word is: “.$input;

在上面的代码里,我们设定了一个数组@completion_list,里面包含了需要补全的名称,Perl就是根据这个列表来对你输入的字符进行补全的。Complete函数是主导这个工作的核心,它的第一个参数是在终端上输出提示输入的说明,第二个参数就是能用于补全的词组列表。

运行这个脚本的时候,你按tab键,Perl会自动用列表中的词来帮你补全,你输入回车确定补全、输入结束后,Perl会把你输入的内容存到变量$input里。

这样,以后就再也不用敲一长串的字符了。

(0) Comments    Read More   
Posted on 06-05-2009
Filed Under (技术) by waterlin

最近,一直在苦苦寻找一个最适合自己的bug追踪系统。我自己平时写的一些小工具,有一些bug需要追踪管理一下,用记事本显得格式太随意了,不好管理。

试了很多有名的工具,如Bugzilla,Mantis,感觉都太厚重了,团队用倒是蛮合适的。

后来想着用XML定义一个日志数据库,一个Bug开一个文件,这样可以详细记录Bug的内容及解决过程、方法等。再写一个前端,用来管理组织这些XML文件。但我个人的bug量不多,更多的时候,是随手写一点想法,这种XML严谨的组织方式,并没有让我觉得更轻松。

尝试着用Emacs Muse记录了一段时间,有一个缺点,就是我写下来的解决方法里,有很多是代码,如果我不加<verse></verse>标签,Muse会尽量地帮我重新转义一下。总的来说,Muse还是偏排版多一点,不适合于记录随想随写的东西。

最后,我发现用Perl的pod来做自己的bug追踪系统挺好的。Pod虽然是个文档系统,但是只要灵活地运用标签也是能做简单的bug追踪系统。Pod的优点是,当你不需要用命令的时候,直接输入你的内容即可,总体来说,比较简洁。

我的pod格式定义如下:

=pod

=head1 project 1

=head2 Bug #000001

=head3 Bug #000001的简单描述或标题

Bug #000001的详细描述,所有的有关内容。。

=head3 Bug Status::Fixed

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000001, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=head2 Bug #000002

=head3 Bug #000002的简单描述或标题

Bug #000002的详细描述,所有的有关内容。。

=head3 Bug Status::Active

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000002, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=head2 Bug #000003

=head3 Bug #000003的简单描述或标题

Bug #000003的详细描述,所有的有关内容。。

=head3 Bug Status::Suspended

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000003, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=cut

把上面的例子代码存成一个文档,比如说,我喜欢存为WaterBug.txt,后缀用.txt是为了方便用其它编辑器查看。

用pod2html的命令生成文档给其他人观看:

pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug

当然,你可以为这个文档写一个你自己的Style Sheet,生成一个打着你的logo的个性化文档:

pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug –css stylesheet.css

在定义我的pod格式时,我分别用ActiveSuspendedFixedOn-hold四种状态来标明Bug的状态,即”正在进行”、”还未开始”、”已经搞定”、”暂时放着”等四种状态,这些状态关键字都是以::开头进行标识。

以这些简单的标记来记录文档,我可以随手写在任何文本文件里,包括Google Docs这些在线文档,即使将来要转成其它格式的文档,也可以轻松地用perl来实现转换。

要查找特定状态的bug,只要搜索一下::Fixed或是::Suspended或是::Active或是::On-hold即可。

(1) Comment    Read More   
Posted on 28-04-2009
Filed Under (技术) by waterlin

最近在写一个比较长的Perl脚本,用来自动化实现做task的流程与步骤。但是,其中有一些很容易出错的步骤,比如说我的VPN没有开、某某服务没启动等,就执行不了一些操作,从而导致脚本运行出错。

这个时候,我只好先修复配置错误,然后重新从头执行脚本。这样浪费了大量的时间,也弄得我很烦躁。工作原本就没太多乐趣,而我,哪里可能记得住这么多琐碎的事呢?

今天写了一个循环控制的东西,能在出错的步骤停止下来,等我修改了出错的步骤(系统环境而非代码本身),又能从中止的地方重新开始。示例代码如下:

use warnings;
use strict;

sub test1 {
print “test1\n”;
}

sub test2 {
print “test2\n”;
}

sub test3 {
print “test3\n”;

}

my $result = undef;

sub controller {
my $code_array = shift;
my ($code,$code_name) = @$code_array;
while (1) {
my $new_result = eval {&$code};
if ($@) {
print “$@ \n Someting is wrong when execute $code_name, please input ENTER when you fix it.”;
<>;
} else {
last;
}
}
}

my @codes = ([\&test1,”test1″],[\&test2,”test2″],[\&test3,”test3″]);

map {controller($_)} @codes;

运行这段代码,会依次执行子函数test1,test2,test3等。

其中的eval语句,是必不可少的!有了eval后,如果子函数运行时出错或执行了die函数,就会返回一个undefined的值,并且错误消息也会存储到$@变量里;如果一切顺序,$@里就是一个空的字符串。有关这个用法,可以详细地看看perldoc里有关eval的说明

可以在test2或是其它子函数里插入一个die来试试中断的效果。

通过这样的结构,我就可以把很长的脚本分成若干个简短的子过程,大大地提高我的工作效率。另外要说明的是,代码本身的问题,并不能通过这样的方法来得到解决;还是得手动修改code,再重新运行。

(0) Comments    Read More