将assert()方法添加到Ruby';什么是内核类?

将assert()方法添加到Ruby';什么是内核类?,ruby,assert,xunit,Ruby,Assert,Xunit,我正在扩展我对Ruby的理解,用Ruby编写一个与Kent Beck的xUnit相当的代码。Python(Kent在中编写)在广泛使用的语言中有一个assert()方法。Ruby没有。我认为添加这个应该很容易,但是内核是放置它的正确位置吗 顺便说一句,我知道Ruby中存在各种单元框架——这是一个学习Ruby习惯用法的练习,而不是“完成一些事情”。您为什么要将assert方法添加到内核模块?为什么不使用另一个名为断言的模块呢 像这样: module Assertions def assert(

我正在扩展我对Ruby的理解,用Ruby编写一个与Kent Beck的xUnit相当的代码。Python(Kent在中编写)在广泛使用的语言中有一个assert()方法。Ruby没有。我认为添加这个应该很容易,但是内核是放置它的正确位置吗


顺便说一句,我知道Ruby中存在各种单元框架——这是一个学习Ruby习惯用法的练习,而不是“完成一些事情”。

您为什么要将assert方法添加到内核模块?为什么不使用另一个名为断言的模块呢

像这样:

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

  # define more assertions here
end
如果您确实需要您的断言在任何地方都可用,请执行以下操作:

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

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

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

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


Ruby的内置单元测试如何看待这个问题,那么,就是每个单独的测试用例类都是的一个子类,其中包含一个“assert”语句,用于检查传递给它的内容的有效性,并记录它以供报告。

不,这不是最佳实践。Ruby中assert()的最佳类比就是

 raise "This is wrong" unless expr

如果您想提供更具体的异常处理,您可以实现自己的异常。这不是特别惯用的,但我认为这是一个好主意。特别是如果这样做:

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

这样,如果您决定不使用DEBUG(或其他方便的开关,我在过去使用过Kernel.do_assert)集运行,则不会产生任何影响。

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

  • xUnit框架使用
    assert
    方法检查您的测试期望。它们用于测试代码中,而不是应用程序代码中
  • 有些语言,如C、Java或Python,包含一个
    assert
    结构,用于在程序的代码中使用,以检查您对其完整性所做的假设。这些检查构建在代码本身内部。它们不是测试时工具,而是开发时工具
我最近写了一封信,还。。它允许您以以下形式编写表达式:

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    
它们可以被停用,以便
assert
invariant
作为空语句进行计算。这样可以避免生产中的任何性能问题。但请注意,建议不要停用它们。只有当它们确实影响性能时,才应停用它们

关于回答说惯用的Ruby方式是使用普通的
raise
语句,我认为它缺乏表现力。断言编程的黄金法则之一是不使用断言进行正常的异常处理。它们是两个完全不同的东西。如果对它们两个使用相同的语法,我认为您的代码将更加晦涩难懂。当然,你失去了停用它们的能力


您可以确信使用断言是一件好事,因为两个人必须阅读经典书籍,如,并将整个章节专门介绍给他们,并推荐使用它们。还有一篇很好的文章,标题是,它很好地说明了什么是断言编程以及何时使用它(它是基于Java的,但概念适用于任何语言)。

我喜欢既能教你,又能完成任务的问题。:)如果[expr],如果您愿意,也可以使用引发运行时错误的
fail。
fail
raise
的别名,不是吗?它们都给出
运行时错误
。(也许有一个更习惯吗?)如果你的软件在生产过程中很难很快地失败,那是很好的,我认为沉默的例外是“捕捉所有异常”的可怕副本。它通常是在糟糕的代码出现问题时应用于糟糕代码的第一个糟糕的绷带。断言和异常是不同的。@nus断言不是为了警告,它们是为了确保在那个地方某些东西总是正确的。如果你的断言在生产中失败了,你肯定会放弃。我还建议Steve Maguire的“编写可靠的代码”,这是一个非常面向C的程序,但是谈论了断言、测试策略和构造函数的想法,这些都适用于方法构造。这不是猴子补丁吗?您正在更改
对象
类。是的,这是经典的猴子补丁。如果您真的必须使
assert
方法在全球范围内可用,那么这就是实现方法。然而,我不建议任何人在非玩具项目中使用这样的猴子补丁。