36.熟悉单元测试工具MiniTest
37.熟悉MiniTest的需求测试
38.使用Mock模拟特定对象
39.力争代码被有效测试过
36.熟悉单元测试工具MiniTest
minitest不是Ruby的标准库中的类,目前是一个gem
#安装minitest
gem install minitest
这个章节的内容会用到第13章节的Version类的例子
#类要实现<=>方法,需要引入Comparable和实现<=>方法
class Version
attr_reader :major, :minor, :patch
include Comparable
def initialize(version)
@major, @minor, @patch = version.split(".").map(&:to_i)
end
def <=>(other)
return nil unless other.is_a?(Version) #如果是属于不同的对象,则返回nil
[major <=> other.major,
minor <=> other.minor,
patch <=> other.patch].detect{ |n| !n.zero? } || 0
end
end
常用法
#引入minitest/autorun模块,运行文件的过程中会执行所有方法,而直接引入minitest不会
#一个标准的测试类应该是MiniTest::Test的子类
#定义方法应该以“test_”开头
#setup方法在测试开始之前执行,teardown方法会在测试结束之后执行
require 'minitest/autorun' #会引入unit testing, spec testing, mock
class VersionTest < MiniTest::Test
def setup
@v1 = Version.new("1.2.3")
end
def test_major_number
v = Version.new("1.2.3")
assert(v.major == 2, "major should be 2")
assert(v.major == @v1.major, "major should be 2")
end
end
一些断言
assert #assert两个参数,第一个参数值为true或者false,如果为false,则错误代码会显示第二个参数的值
assert_not #同理
assert_equal #assert_equal包括三个参数,第一个参数是期望值,第二个参数是实际值,第三个参数是错误后的值
assert_not_equal #同理
使用rake方法来执行多个文件中的测试方法
http://www.virtuouscode.com/2014/04/22/rake-part-2-file-lists/
37.熟悉MiniTest的需求测试
这里主要介绍minitest中rspec风格的测试样式
#代码示例,省略Version类的定义
require 'minitest/autorun'
describe("demo") do
describe("when parsing") do
before do
@version = Version.new("1.2.3")
end
it("create three integers") do
@version.major.must_equal(1)
end
end
end
和36章节中minitest中一般测试中,可以发现和rspec测试风格类似的对应关系
describe => class
it => def
before =>setup
其中判断方法must_equal方法可以被assert方法取代
it("create three integers") do
@version.major.must_equal(1)
end
#替代方法
it("create three integers") do
assert @version.major==1
end
总结:这个章节的内容可以不必记住,但是可以认识到这种一般测试之外和rspec测试风格极为类似的一种测试风格。
38.使用Mock模拟特定对象
39.力争代码被有效测试过
ruby是解释型语言,只有被运行的时候才能发现代码是否存在问题,像java这种是编译型语言(在代码运行之前进行编译),代码编译的时候会发现错误。
测试的几种方式介绍:
快乐路径测试:被测代码的前提条件都已经被满足的前提下,仅测试有效出入的测试方法。
异常路径测试:输入各种各样的值并保证每一个分支都被执行过。
模糊测试:一般应用于安全领域,向一个程序或者特定的方法输入大量随机的数据,找出程序崩溃或暴露出安全漏洞的一种方法,采用模糊测试方法,我们的关注点从测试结果是通过还是失败,转移到是否能找到程序崩溃或者异常问题上。
属性测试:和模糊测试类似,属性测试也使用随时输入来测试你的代码,但所添加测试的期望是确定的,属性测试相对于模糊测试来说,显得更加实际,因为测试是有限的。
属性测试示例
执行基于属性的测试时,需要定义代码应该满足的属性,然后工具会生成大量的测试用例爱试图使属性测试失败。
#执行代码,ruby demo.rb
require 'mrproper'
class Version
def initialize(version)
@major, @minor, @patch = version.split(".").map(&:to_i)
end
def to_s
[@major, @minor, @patch].join(".")
end
end
properties("Version") do
data([Integer, Integer, Integer])
property("new(str).to_s == str") do |data|
str = data.join('.')
assert_equal(str, Version.new(str).to_s)
end
end
模糊测试示例:
#代码执行 fuzzbert demo.rb
require 'uri'
require 'net/http'
require 'fuzzbert'
class Monitor
attr_accessor :server
def initialize(server)
@server = server
end
def alive?
response = get
true if response.code == "200"
rescue SocketError => e
false
end
private
def get
Net::HTTP.get_response(URI(server))
end
end
fuzz("uri::http.get_response") do
data("cc") do
FuzzBert::Generators.random
end
deploy do |data|
Net::HTTP.get_response(URI(data))
end
end
检查测试的覆盖率工具:SimpleCov