Ruby 手册 | 30 - Ruby 的单元测试

387 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

一、Ruby 测试框架

Ruby 中提供了 Test::Unit 的测试框架,用于单元测试,可以方便的表示单元、组织和调用单元测试。

require 'test/unit'

class HelloTest < Test::Unit::TestCase
  def test_hello
    puts "测试栗子"
    assert true
  end
end

执行上述代码,输出结果如下:

图片.png

上述代码中首先使用 require 引用了 Ruby 的单元测试标准库,然后创建了一个 HelloTest 类,这个类就是一个测试用例 TestCase,且一定要继承 Test::Unit::TestCase

HelloTest 测试用例类中包含了一个 test_hello 方法以及一个断言,assert 后跟 true 或者 false 来判断测试用例执行成功或者失败。

一个测试用例中可以包含多个方法,用来测试不同的功能,且各个测试方法之间是互相独立的,除了普通的测试方法外,测试用例中还包含了两个特殊的方法,既 setup 方法和 teardown 方法。

setup 方法在每个测试方法执行前被执行,可以用于准备数据或者初始化等操作,teardown 方法在每个测试方法运行后执行,用于清理工作。

require 'test/unit'

class HelloTest < Test::Unit::TestCase

  def setup
    puts "每个测试方法执行前执行"
  end

  def teardown
    puts "每个测试方法执行后执行"
  end

  def test_hello
    puts "测试栗子"
    assert true
  end

  def test_hi
    puts "测试栗子2"
    assert true
  end
end

执行上述代码,输出结果如下:

图片.png

test_hellotest_hi 方法执行前后都执行了 setupteardown 方法。

二、断言 Assert

断言是测试用例中非常重要的部分,没有断言也就无法判断测试用例执行的结果是成功或者失败,Ruby 单元测试框架中提供非常多的断言方法。

断言方法方法说明
assert(boolean, [message])如果 boolean 为 false 或者 nil 则失败
assert_nil(obj, [message]), assert_not_nil(obj, [message])判断是否为 nil 或者不为 nil
assert_equal(expected, actual, [message]), assert_not_equal(expected, actual, [message])判断相等或者不相等
assert_in_delta(expected_float, actual_float, [message])预期实际的浮点值出于预期值的 delta 偏差内
assert_raise(Exception, ...){block}, assert_not_raise(Exception, ...)预期 block 将会或者不会引发参数列出异常
assert_instance)of(kclass, obj, [message]), assert_kind_of(kclass, obj, [message]预期 obj 是 kclass 实例或者子类
assert_response_to(obj, message, [message])预期 obj 能够响应 message
assert_match(regex, string, [message]), assert_not_match(regex, string, [message])预期 string 符合或者不符合 regex
assert_same(expected, actual, [message]), assert_not_same(expected, actual, [message]预期 相同或者不相同
require 'test/unit'

class Calculator
  def add(x, y)
    return x + y
  end

  def sub(x, y)
    return x - y
  end

  def multi(x, y)
    return x * y
  end

  def divide(x, y)
    return x / y
  end
end

class CaculatorTest < Test::Unit::TestCase

  def setup
    @cal = Calculator.new
  end

  def test_add
    actual_res = @cal.add(1, 2)
    expected_res = 3
    assert_equal(expected_res, actual_res, ["实际结果与预期结果不一致,测试失败"])
  end

  def test_sub
    actual_res = @cal.sub(1, 2)
    expected_res = -1
    assert_equal(expected_res, actual_res, ["实际结果与预期结果不一致,测试失败"])
  end

  def test_multi
    actual_res = @cal.multi(1, 2)
    expected_res = 2
    assert_equal(expected_res, actual_res, ["实际结果与预期结果不一致,测试失败"])
  end

  def test_divide
    assert_raise(RuntimeError) {@cal.divide(2, 0)}
  end
end

创建一个 Calculator 类,该类中包含了四个方法,接着创建一个 CalculatorTest 类,针对 Calculator 类中的四个方法分别创建一个测试方法。

执行上述代码,输出结果如下:

.....

4 tests, 4 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications

Test suite finished: 0.007685 seconds
···