单元测试是软件开发过程中不可或缺的一部分,它帮助开发者验证代码的正确性,并确保代码在修改或重构时依然能够正常工作。在 Ruby 中,常用的单元测试框架有 RSpec 和 Minitest。本章将详细介绍如何使用这两种框架进行单元测试。
RSpec 入门
安装 RSpec
首先,你需要在你的项目中安装 RSpec。可以通过 Bundler 来管理依赖,确保每个项目的依赖都独立。
# Gemfile gem 'rspec', group: :test
然后运行 bundle install 来安装 RSpec。
编写第一个测试
假设你有一个简单的 Ruby 类 Calculator,用于执行基本的数学运算。
// www.javascriptcn.com code example
# lib/calculator.rb
class Calculator
def add(a, b)
a + b
end
def subtract(a, b)
a - b
end
end接下来,我们为这个类编写一些测试。
// www.javascriptcn.com code example
# spec/calculator_spec.rb
require 'calculator'
require 'rspec'
RSpec.describe Calculator do
describe '#add' do
it 'returns the sum of two numbers' do
calculator = Calculator.new
expect(calculator.add(5, 3)).to eq(8)
end
end
describe '#subtract' do
it 'returns the difference between two numbers' do
calculator = Calculator.new
expect(calculator.subtract(10, 4)).to eq(6)
end
end
end运行测试
你可以通过以下命令来运行测试:
rspec
更多的 RSpec 特性
用 let 和 subject 简化代码
当你在多个测试中重复使用同一个对象时,可以使用 let 或 subject 来简化代码。
// www.javascriptcn.com code example
# spec/calculator_spec.rb
require 'calculator'
require 'rspec'
RSpec.describe Calculator do
let(:calculator) { Calculator.new }
describe '#add' do
it 'returns the sum of two numbers' do
expect(calculator.add(5, 3)).to eq(8)
end
end
describe '#subtract' do
it 'returns the difference between two numbers' do
expect(calculator.subtract(10, 4)).to eq(6)
end
end
end使用 before 和 after 钩子
在某些情况下,你可能需要在每个测试之前或之后执行一些操作。你可以使用 before 和 after 钩子来实现这一点。
// www.javascriptcn.com code example
# spec/calculator_spec.rb
require 'calculator'
require 'rspec'
RSpec.describe Calculator do
let(:calculator) { Calculator.new }
before do
# 在每个测试之前执行的操作
puts "Before each test"
end
after do
# 在每个测试之后执行的操作
puts "After each test"
end
describe '#add' do
it 'returns the sum of two numbers' do
expect(calculator.add(5, 3)).to eq(8)
end
end
describe '#subtract' do
it 'returns the difference between two numbers' do
expect(calculator.subtract(10, 4)).to eq(6)
end
end
endMinitest 入门
Minitest 是 Ruby 自带的一个轻量级测试框架,适合那些喜欢简洁风格的开发者。
编写第一个测试
假设我们有同样的 Calculator 类,我们也可以为它编写测试。
// www.javascriptcn.com code example
# test/calculator_test.rb
require 'minitest/autorun'
require_relative '../lib/calculator'
class TestCalculator < Minitest::Test
def setup
@calculator = Calculator.new
end
def test_add
assert_equal 8, @calculator.add(5, 3)
end
def test_subtract
assert_equal 6, @calculator.subtract(10, 4)
end
end运行测试
你可以通过以下命令来运行测试:
ruby -Itest test/calculator_test.rb
更多的 Minitest 特性
使用 setup 方法
setup 方法允许你在每个测试之前执行一些初始化操作。
// www.javascriptcn.com code example
# test/calculator_test.rb
require 'minitest/autorun'
require_relative '../lib/calculator'
class TestCalculator < Minitest::Test
def setup
@calculator = Calculator.new
end
def test_add
assert_equal 8, @calculator.add(5, 3)
end
def test_subtract
assert_equal 6, @calculator.subtract(10, 4)
end
end使用 teardown 方法
与 setup 相对应的是 teardown 方法,它会在每个测试之后执行。
// www.javascriptcn.com code example
# test/calculator_test.rb
require 'minitest/autorun'
require_relative '../lib/calculator'
class TestCalculator < Minitest::Test
def setup
@calculator = Calculator.new
end
def teardown
@calculator = nil
end
def test_add
assert_equal 8, @calculator.add(5, 3)
end
def test_subtract
assert_equal 6, @calculator.subtract(10, 4)
end
end总结
通过本章的学习,你应该已经掌握了如何使用 RSpec 和 Minitest 进行单元测试的基本知识。这两种框架各有特点,可以根据自己的喜好和项目需求选择合适的工具。记住,良好的测试习惯可以帮助你构建更可靠、更健壮的软件系统。