Setup RSpec for Ruby
學習怎麼用 RSpec 測試一個 Ruby 專案。
例子:HTML 標籤生成器,譬如來寫一個可以產生 HTML 標籤的 Ruby 代碼。
首先建立一個 html
資料夾,初始化 RSpec,新建兩個文件 html.rb
與 spec/html_spec.rb
:
$ mkdir html
$ rspec --init
$ touch html.rb
$ touch spec/html_spec.rb
html.rb
填入以下內容:
class HTML
def self.tag(tag, content, attributes = {})
%Q(<#{tag} #{extract(attributes)}>#{content}</#{tag}>)
end
private
def self.extract(attributes)
attributes.inject("") do |attrs, (attr, value)|
attrs << " " if attrs != ""
attrs << %(#{attr}="#{value}")
end
end
end
我們寫了一個 HTML
類別,有一個 .tag
類別方法!這個方法接受三個參數:標籤名稱、標籤內容、以及標籤屬性(可選)。
譬如
HTML.tag("title", "My Awesome Website")
就會輸出
<title>My Awesome Website</title>
接下來在 spec/html_spec.rb
編寫測試。
RSpec 的“期望”語法:
expect(實際的程式).to eq(期望值)
expect(1+1).to eq 2
來測試兩個例子,spec/html_spec.rb
填入以下內容::
require_relative "../html"
RSpec.describe HTML do
describe ".tag" do
it "Create a link to Google" do
result = HTML.tag("a", "Google", href: "https://google.com")
expect(result).to eq(%{<a href="https://google.com">Google</a>})
end
it "Create a link to Google and open in new page" do
result = HTML.tag("a", "Google", href: "https://google.com", target: "_blank")
expect(result).to eq(%{<a href="https://google.com" target="_blank">Google</a>})
end
end
end
require_relative "../html"
這行引入 html.rb
。
describe ".tag"
測試 HTML 類別的 class method tag
。
接著編寫了兩個簡單的測試。
運行測試
$ rspec
..
Finished in 0.00077 seconds (files took 0.23713 seconds to load)
2 examples, 0 failures
可以看到 RSpec 執行測試其實速度相當快,只需要 0.00077 秒!但為什麼常聽到人說,RSpec 很慢,用 Minitest 比較好,其實 RSpec 跟 Minitest 執行速度不相上下,慢的是載入整個 Rails 環境。RSpec 以前幾乎都是跟著 Rails 搭配使用,所以就一直背負這個污名,其實一點都不慢!
接下來,讓我們加一個 rspec
命令的命令行參數--format documentation
,再跑測試看看:
$ rspec --format documentation
HTML
.tag
Create a link to Google
Create a link to Google and open in new page
Finished in 0.0011 seconds (files took 0.1095 seconds to load)
2 examples, 0 failures
可以看到,測試看起來就像是文檔一樣!若希望每次執行都像是讀文檔一樣,就把這個命令行參數加到 .rspec
裡即可,之後使用 rspec
跑測試時,都會默認加上這個參數。
完整步驟請參考:https://github.com/JuanitoFatas/setup-rspec-for-ruby/commits/master