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