2014-06-10 49 views
1

我在新的Rails項目上使用MiniTest,這是我第一次真正在做測試。當測試失敗的消息看起來像這樣minitest的可讀測試名稱

1) Failure: 
Category::when created#test_0002_must have a unique name [/home/caleb/workspace/buzz/test/models/category_test.rb:10]: 
Expected: true 
    Actual: false 

你能不能改#test_0002_到另一個字符串,使錯誤更具可讀性?我知道這是一個小問題,但這似乎應該得到支持。

# Example test 
require 'test_helper' 

describe Category do 
    describe 'when created' do 
    unique = false 
    it 'must not have a unique name' do 
     unique.must_equal false 
    end 
    it 'must have a unique name' do 
     unique.must_equal true 
    end 
    end 
end 

回答

3

好吧,這裏有很多內容可以涵蓋。和我一起裸露。

首先,測試名稱是可讀的。他們100%準確。當您使用spec DSL時,您仍然在創建測試類和測試方法。在你的情況下,你的課程是Category::when created,你的測試方法是test_0002_must have a unique name。它們之間的#是一個非常常見的Ruby實現類的方法,這是你的測試方法。當你使用classdef時,你不能創建帶有空格的類或方法,但是當你以編程方式創建它們時,你可以。在運行你的代碼時,Ruby不關心它們中是否有空格。

二,我們可以影響測試類和方法的顯示。該文本來自撥打Minitest::Test#to_s。這是什麼樣的:

def to_s # :nodoc: 
    return location if passed? and not skipped? 

    failures.map { |failure| 
    "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n" 
    }.join "\n" 
end 

當測試失敗,則返回更多的信息,包括失敗的原因。但我們關心的是location。這是什麼樣子:

def location 
    loc = " [#{self.failure.location}]" unless passed? or error? 
    "#{self.class}##{self.name}#{loc}" 
end 

啊,好一些。在最後一行,您可以清楚地看到它正在打印類和方法名稱。如果測試失敗,該位置還包括定義該方法的文件名。讓我們將這些值分解出來,以便它們不是內聯的:

def location 
    loc = " [#{self.failure.location}]" unless passed? or error? 
    test_class = self.class 
    test_name = self.name 
    "#{test_class}##{test_name}#{loc}" 
end 

好的,稍微清楚一點。首先是測試課程,然後是#,然後是測試名稱,如果測試未通過,則是位置。現在我們把它們分開了,我們可以稍微修改它們。讓我們用/來分隔類的命名空間和測試方法:

def location 
    loc = " [#{self.failure.location}]" unless passed? or error? 
    test_class = self.class.to_s.gsub "::", "/" 
    test_name = self.name 
    "#{test_class}/#{test_name}#{loc}" 
end 

大。現在讓我們從測試方法的開始處刪除test_0002_。這是規範中的DSL補充,並通過刪除它,我們可以把它傳遞給it塊匹配字符串:

def location 
    loc = " [#{self.failure.location}]" unless passed? or error? 
    test_class = self.class.to_s.gsub "::", "/" 
    test_name = self.name.to_s.gsub /\Atest_\d{4,}_/, "" 
    "#{test_class}/#{test_name}#{loc}" 
end 

現在,您的測試輸出將是這樣的:

1) Failure: 
Category/when created/must have a unique name [/home/caleb/workspace/buzz/test/models/category_test.rb:10]: 
Expected: true 
    Actual: false 

MINITEST與任何其他Ruby庫沒有區別。規範DSL僅僅是一個用於創建測試類和方法的薄包裝器。您可以改變測試對象的行爲以按照您希望的方式工作。

TL; DR以下內容添加到您的test/test_helper.rb文件:

class Minitest::Test 
    def location 
    loc = " [#{self.failure.location}]" unless passed? or error? 
    test_class = self.class.to_s.gsub "::", "/" 
    test_name = self.name.to_s.gsub /\Atest_\d{4,}_/, "" 
    "#{test_class}/#{test_name}#{loc}" 
    end 
end 
+0

真棒響應,我希望這樣的事情,但我有沒有掛鉤或特效提取測試名稱格式有點驚訝。我猜ruby的公開課不需要這些。 – everett1992