RSpec 实例详解(译)

原文链接:https://www.rubyguides.com/2018/07/rspec-tutorial/

你想学习如何使用RSpec为Ruby应用程序编写测试用例吗?

那你来对地方了!

在本教程中,我将想你展示如何去做。

一、为什么要编写测试用例?

它建立了一个防止错误的安全网,如果你没有完善的测试系统,你不敢轻易修改代码,因为可能会破坏一些东西;

它会提升你的自信心;

它能帮助你记录代码,你的测试描述了程序功能;

它可以给你反馈,它可以确保代码产生预期的结果。

如果你想写一些复杂的逻辑,你需要确保它可以用于许多不同的输入,而不仅仅是您想出的一个示例。

二、RSpec 入门

步骤1:初始化

require 'rspec/autorun'
#create a describe block to group all your tests together & to tell RSpec which class you are testing.
describe Factorial do
  # ...
end

步骤2:it block

describe Factorial do
  it "does something" do
    # ...
  end
end

三、RSpec测试示例

describe Factorial do
  it "finds the factorial of 5" do
    calculator = Factorial.new
    expect(calculator.factorial_of(5)).to eq(120)
  end
end

当您运行此代码时,您将获得以下信息:

uninitialized constant Factorial (NameError)

这是正常的,因为我们还没有 Factorial 类,创建一个

class Factorial
end

然后又提示

undefined method 'factorial_of'

同样的创建method factorial_of

class Factorial
  def factorial_of
  end
end

再运行

wrong number of arguments (given 1, expected 0)

不用害怕错误出现,它们是反馈,最终通向正确的道理。

向factorial_of方法传参数

class Factorial
  def factorial_of(n)
  end
end

运行后你会发现测试失败

expected: 120
     got: nil

接下来实现这个方法

class Factorial
  def factorial_of(n)
    (1..n).inject(:*)
  end
end

你将获得第一个通过的测试用例

.
Finished in 0.00315 seconds (files took 0.09083 seconds to load)
1 example, 0 failures

您首先编写测试用例,然后让测试指导您下一步需要做什么。

四、RSpec Let 方法

如果要编写很多测试用例,并且重复使用相同的对象,你可以用let语句定义他们

例如

describe Factorial do
  let(:calculator) { Factorial.new }
  it "finds the factorial of 5" do  
    expect(calculator.factorial_of(5)).to eq(120)
  end
end

现在你可以在同一describe块下的所有测试方法中使用calculator

但是你要知道的是,在你第一次使用该对象之前,let 不会创建它,这个可能会带来一些副作用,比如创建数据库实例,或者写入文件。

最好能避免这些副作用,但是如果你做不到,那请使用let! 方法。

let!(:user) { User.create("rspec@rubyguides.com") }

let!方法不是懒加载的,所以对象会在运行前被创建

五、如何使用Subject Method

let的另一个版本是subject,唯一不同的是,只能拥有一个主题,它是要测试的主要对象的实例。

RSpec已经创建了一个默认主题,如下所示:

subject { Factorial.new }

这个被称为 “implicit subject”

你可以像这样使用它:

describe Factorial do
  it "finds the factorial of 5" do  
    expect(subject.factorial_of(5)).to eq(120)
  end
end

您可以给主题起一个名字:

subject(:calculator) { Factorial.new }

六、如何在所有测试之前运行代码

RSpec具有执行挂钩,可以使用它在每次测试或整个测试组之前和之后运行某些东西。

describe Shop do
  before(:all) { Shop.prepare_database }
  after (:all) { Shop.cleanup_database }
end

如果要为每个测试用例运行此代码,则可以使用:each代替:all。

七、如何创建测试子组

如果要在应用中测试不同的场景,则将相关测试组合在一起可能会有所帮助。

使用RSpec中的context block来执行此操作。

describe Course do
  context "when user is logged in" do
    it "displays the course lessons" do
    end
    it "displays the course description" do
    end
  end
  context "when user it NOT logged in" do
    it "redirects to login page" do
    end
    it "it shows a message" do
    end
  end
end

八、RSpec Expectations & Matchers

你可能还记得这个例子

expect(calculator.factorial_of(5)).to eq(120)

eq 就是 matcher的一种,还有一些其他的匹配器

例如 be_something

expect(nil).to be_nil
  • include (for arrays & hashes)
  • start_with
  • end_with
  • match (for regular expression matching)
  • be_between
  • have_key / have_value (for hashes)
  • be_instance_of
  • respond_to
  • have_attributes (for testing instance variables)

这些文章可以参考

 https://www.jianshu.com/p/1db9ee327357?lan=cn

https://ruby-china.org/topics/33592

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值