2008-09-29 77 views
61

我正在通過在Ruby中編寫相當於Kent Beck的xUnit的擴展Ruby知識。 Python(肯特寫入的)在廣泛使用的語言中有一個assert()方法。 Ruby不會。我認爲應該很容易添加這個,但是Kernel是放置它的正確位置?向Ruby的Kernel類添加assert()方法是否是慣用的Ruby?

BTW,我知道紅寶石各個單元框架的存在 - 這是學習Ruby的成語,而不是「得到的東西做」的練習。

+3

我喜歡遇到的兩個問題:教你,完成一些事情。 :) – 2008-09-29 14:35:02

回答

77

不,這不是最佳做法。最好的比喻斷言()在Ruby中只是提高

raise "This is wrong" unless expr 

,如果你想提供更具體的異常處理

+22

如果你喜歡,你也可以使用`fail if [expr]`,這會引發運行時錯誤。 – 2010-02-25 03:38:20

14

將斷言方法添加到內核模塊的原因是什麼?爲什麼不使用另一個叫做Assertions的模塊呢?

像這樣:

module Assertions 
    def assert(param) 
    # do something with param 
    end 

    # define more assertions here 
end 

如果你真的需要你的斷言可用隨處做這樣的事情:

class Object 
    include Assertions 
end 

聲明:我沒有測試的代碼,但在原則上我會這樣做。

+1

這不是猴子補丁嗎?你正在改變`Object`類。 – tsikov 2016-02-10 18:12:26

+0

是的,那是古典的猴子補丁。這是做到這一點的方法,如果你真的必須使全局可用的`assert`方法。但是,我不會建議任何人在非玩具項目中使用這種猴子補丁。 – 2017-01-23 09:52:41

4

我的理解是,您正在編寫自己的測試套件,以此來更熟悉Ruby。因此,雖然Test :: Unit可能作爲指導有用,但它可能不是您要查找的內容(因爲它已經完成了這項工作)。

也就是說,python的斷言(對我來說至少)更類似於C的assert(3)。它不是專門爲單元測試而設計的,而是爲了抓住「永遠不會發生」的情況。

Ruby的內置單元測試如何傾向於查看問題,那麼每個測試用例類都是TestCase的子類,並且包含一個「assert」語句,用於檢查傳遞給它的內容的有效性並記錄下來進行報告。

6

這不是特別地道,你可以實現自己的異常,但我認爲這是一個好主意。特別是如果做過這樣的:

def assert(msg=nil) 
    if DEBUG 
     raise msg || "Assertion failed!" unless yield 
    end 
end 

這樣,如果你決定不與調試運行沒有影響(或者其他方便的開關,我用Kernel.do_assert過去)集。

25

我認爲在Ruby中使用斷言是完全有效的。但是您提到了兩件不同的事情:

  • xUnit框架使用assert方法來檢查您的測試期望值。它們旨在用於測試代碼中,而不是用於應用程序代碼中。
  • 一些像C,Java或Python這樣的語言包含一個assert構造,用於在程序代碼中使用,以檢查您對其完整性的假設。這些檢查是在代碼本身內部構建的。它們不是測試時間的工具,而是開發時間的工具。

我最近寫了solid_assert: a little Ruby library implementing a Ruby assertion utilitya post in my blog explaining its motivation。它讓你寫的表達形式:

assert some_string != "some value" 
assert clients.empty?, "Isn't the clients list empty?" 

invariant "Lists with different sizes?" do 
    one_variable = calculate_some_value 
    other_variable = calculate_some_other_value 
    one_variable > other_variable 
end  

他們可以這樣被停用assertinvariant得到評估爲空語句。這可以避免生產中的任何性能問題。但請注意,The Pragmatic Programmers建議不要停用它們。如果它們真的影響到性能,你應該只關閉它們。

關於回答說,習慣Ruby方式使用正常raise聲明,我認爲它缺乏表達性。斷言編程的一個黃金法則是不使用斷言來進行正常的異常處理。他們是兩個完全不同的東西。如果你對它們兩個使用相同的語法,我認爲你的代碼會更加模糊。當然,你失去了去激活它們的能力。

你可以確信,使用斷言是一件好事,因爲兩者必須閱讀經典書籍像The Pragmatic Programmer From Journeyman to MasterCode Complete奉獻全部分給他們,並建議其使用。還有一篇很好的文章,標題爲Programming with assertions,很好地說明了什麼是自信的編程和何時使用它(它基於Java,但概念適用於任何語言)。

相關問題