在Ruby的Kernel类中增加一个assert()方法是否是惯用的Ruby?
我正在通过在Ruby中编写一个相当于Kent Beck的xUnit的扩展Ruby的理解。 Python(肯特写入)有一个assert()方法在广泛使用的语言。 Ruby不会。 我认为应该很容易添加这个,但内核是正确的地方呢?
顺便说一句, 我知道Ruby中各种单元框架的存在 – 这是学习Ruby成语的练习,而不是“完成某件事”。
不,这不是最佳做法。 在Ruby中assert()的最好的比喻就是提高
raise "This is wrong" unless expr
如果要提供更具体的exception处理,则可以实现自己的exception
我认为在Ruby中使用断言是完全有效的。 但是你提到了两件不同的事情:
- xUnit框架使用
assert
方法来检查您的testing期望值。 它们旨在用于您的testing代码中,而不是在您的应用程序代码中。 - 一些像C,Java或Python这样的语言包含一个
assert
结构,用于在你的程序代码中使用,来检查你对它们完整性的假设。 这些检查是在代码本身内部构build的。 他们不是一个testing时间的工具,而是一个开发时间的工具。
我最近写了solid_assert:一个小Ruby库实现一个Ruby断言实用程序 ,也是在我的博客解释其动机的一篇文章 ..它让你写在表单中的forms:
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
被评估为空的语句。 这可以避免生产中的任何性能问题。 但请注意, “实用程序员”build议不要将其停用。 如果真的影响到演出,你应该停用它们。
对于那种习惯用Ruby的方式使用正常的raise
语句的回答,我觉得它缺乏expression能力。 断言编程的黄金法则之一是不使用断言进行正常的exception处理。 他们是两个完全不同的东西。 如果你对它们两个使用相同的语法,我认为你的代码会更加模糊。 当然,你失去了去激活它们的能力。
你可以相信,使用断言是一件好事,因为两本必读的经典着作,如“从熟人到硕士的实用程序员”和“完整代码”,将全部内容奉献给他们,并推荐他们使用。 还有一篇很好的文章,题为“ 用断言编程”很好地说明了什么是自信的编程和何时使用它(它基于Java,但概念适用于任何语言)。
你将assert方法添加到内核模块的原因是什么? 为什么不使用另一个称为Assertions
模块呢?
喜欢这个:
module Assertions def assert(param) # do something with param end # define more assertions here end
如果你真的需要你的断言在任何地方都可以这样做:
class Object include Assertions end
免责声明:我没有testing代码,但原则上我会这样做。
这不是特别习惯,但我认为这是一个好主意。 特别是如果这样做:
def assert(msg=nil) if DEBUG raise msg || "Assertion failed!" unless yield end end
这样,如果您决定不使用DEBUG(或者其他方便的开关,我以前使用过Kernel.do_assert)来运行,那么这个方法没有任何影响。
我的理解是,你正在编写自己的testing套件,以此来更熟悉Ruby。 所以,虽然Test :: Unit可能是有用的,但它可能不是你正在寻找的东西(因为它已经完成了这个工作)。
也就是说,python的断言(对我来说至less)更类似于C的断言(3) 。 它不是专门为unit testing而devise的,而是用来捕捉“永远不会发生”的情况。
Ruby的内置unit testing如何倾向于查看问题,那么每个单独的testing用例类都是TestCase的一个子类,并且包含一个“assert”语句,该语句检查传递给它的内容的有效性并将其logging下来报告。