在Ruby的Kernel类中添加assert()方法是惯用的Ruby吗?

时间:2008-09-29 08:39:16

标签: ruby assert xunit

我通过在Ruby中编写相当于Kent Beck的xUnit来扩展我的Ruby理解。 Python(Kent写入)在语言中有一个assert()方法,该方法被广泛使用。 Ruby没有。我认为添加这个应该很容易,但内核是否适合放置它?

BTW,我知道Ruby中存在各种单元框架 - 这是学习Ruby习语的练习,而不是“完成某些事情”。

5 个答案:

答案 0 :(得分:90)

不,这不是最佳做法。在Ruby中断言()的最好类比就是提高

 raise "This is wrong" unless expr

如果要提供更具体的异常处理,可以实现自己的异常

答案 1 :(得分:28)

我认为在Ruby中使用asserts是完全有效的。但是你提到了两件不同的事情:

  • 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,但概念适用于任何语言)。

答案 2 :(得分:14)

将断言方法添加到内核模块的原因是什么?为什么不使用另一个名为Assertions的模块?

像这样:

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

  # define more assertions here
end

如果您真的需要断言无处不在,请执行以下操作:

class Object
  include Assertions
end

免责声明:我没有测试代码,但原则上我会这样做。

答案 3 :(得分:6)

这不是特别惯用,但我认为这是一个好主意。特别是如果这样做:

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

如果您决定不使用DEBUG(或其他一些方便的开关,我过去使用过Kernel.do_assert)设置,那么没有任何影响。

答案 4 :(得分:4)

我的理解是,您正在编写自己的测试套件,以此来熟悉Ruby。因此,尽管Test :: Unit可能对您有用,但它可能不是您想要的(因为它已经完成了工作)。

那就是说,python的断言是(至少对我来说),更类似于C assert(3)。它不是专门为单元测试而设计的,而是用于捕捉“这应该永远不会发生”的情况。

Ruby的内置单元测试如何倾向于查看问题,那么,每个单独的测试用例类都是TestCase的子类,并且包含一个“断言”语句,用于检查所有内容的有效性。传递给它并将其记录下来进行报告。