Ruby 从测试框架中期待什么 Ruby 代码?

cyri_ · 2021年07月03日 · 780 次阅读

你知道当你使用你喜欢的测试框架的DSL时,会产生什么样的代码吗?

作为一个开发者,你可能有兴趣知道。也许直接写出来太吓人了。或者它可能比 minitest 测试集更轻。

总之,为了尝试回答这个问题,同时避免 RSpec 和 minitest 之间无休止的争论,我将在本文中使用RSpec clone 项目。

什么是 RSpec clone?

这个项目是对 RSpec 的一个最小化的重新实现,强调正确性、安全性和标准化。

RSpec clone 试图实现社区RSpec 风格指南中列出的准则和最佳实践。大多数 RSpec 的 DSL 的实现是为了表达所需的结果。没有什么神奇的力量。

What did you RSpec?

为了快速了解该框架是如何构建和执行测试的,我将向你展示 DSL 语法和生成的 Ruby 代码之间的对应关系。为了便于阅读,这些对应关系是按方法分组的。

从 DSL 到 Ruby

describe 该方法

当我写:

RSpec.describe String do
end

我希望能产生这样的代码:

Class.new do
  private

  def described_class
    String
  end
end

context 该方法

当我写:

RSpec.context "when in a context" do
end

我希望能产生这样的代码:

Class.new do
end

subject 该方法

当我写:

RSpec.describe ".subject" do
  subject do
    "foo"
  end
end

我希望能产生这样的代码:

Class.new do
  private

  def subject
    "foo"
  end
end

嵌入的 describe 该方法

当我写:

RSpec.describe ".describe" do
  describe "embedded describe" do
  end
end

我希望能产生这样的代码:

base = Class.new do
end

Class.new(base) do
end

let 该方法

当我写:

RSpec.describe ".let" do
  let(:answer_to_everything) { 41 + one }
  let(:one) { 1 }
end

我希望能产生这样的代码:

Class.new do
  private

  def answer_to_everything
    41 + one
  end

  def one
    1
  end
end

before 该方法

当我写:

RSpec.describe ".before" do
  before do
    puts "hello"
  end
end

我希望能产生这样的代码:

Class.new do
  private

  def initialize
    puts "hello"
  end
end

expect 该方法

当我写:

RSpec.describe "#expect" do
  it { expect(41.next).to be(42) }
end

我希望能产生这样的代码:

description = Class.new do
end

require "matchi/rspec"
require "r_spec/clone/expectation_target"

example = Class.new(description) { include Matchi::Helper }
sandbox = example.new
sandbox.instance_eval { ExpectationTarget::Value.new(41.next).to be(42) }

而且我希望看到这种信息:

Success: expected to be 42.

用 Ruby 测试是很有趣的!

除非你不写测试,使用这样一个 DSL 接口的好处是,它限制了在规范中引入可能导致错误的额外逻辑,鼓励使用算法复杂度较低的良好的 Ruby 模式,并使 Ruby 代码更短,更(机器)可读。

来自 Adam Hawkins

RSpec 是一种特定领域的测试语言,而 minitest 是 Ruby。

我希望你喜欢RSpec clone,就像我喜欢这两样。谢谢你。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号