Ruby on rails Rails TDD-先写什么

Ruby on rails Rails TDD-先写什么,ruby-on-rails,tdd,Ruby On Rails,Tdd,我刚刚开始使用Rails进行TDD。让我困惑的是“何时编写测试”。所有指南都建议您应该在编写任何代码之前编写测试,但是如果我创建一个Person模型,然后在编写任何代码之前编写以下测试 p = Person.new p.firstname = "mikey" p.lastname = "hogarth" assert_equal p.fullname, "mikey hogarth" 然后测试本身不会失败,它会崩溃!因为我还没有实现“fullname”方法,所以我会得到一个运行时错误。因此,在

我刚刚开始使用Rails进行TDD。让我困惑的是“何时编写测试”。所有指南都建议您应该在编写任何代码之前编写测试,但是如果我创建一个Person模型,然后在编写任何代码之前编写以下测试

p = Person.new
p.firstname = "mikey"
p.lastname = "hogarth"
assert_equal p.fullname, "mikey hogarth"
然后测试本身不会失败,它会崩溃!因为我还没有实现“fullname”方法,所以我会得到一个运行时错误。因此,在编写代码之前,我不可能让测试失败

TDD编码器通常如何处理这种情况?基本上是使用虚拟方法存根还是有更好的方法

==编辑===

提出了很多好主意。我最终决定,以下选项实现了我想做的最优雅的事情

if p.respond_to? "fullname"
  assert_equal "Mikey Hogarth", p.fullname
else
  flunk "fullname not implemented"
end
==第二次编辑===


如果你无意中发现了这个答案,那么我的TDD方法似乎就是问题所在,因此,尽管上面的代码可以工作,但这并不是一个好的实践。

你想编写你希望拥有的代码。在C风格的语言/静态编译的语言中,上述代码甚至不会编译,因为您正确地指出代码不存在。这很好,然后您可以实现最小值来生成代码以运行测试。换句话说,您的测试驱动您的设计

我的Ruby非常生锈,但在上面的示例中,对于不存在的方法/属性,会抛出类似于
method\u missing
的东西。因此,您将创建它们

class Person
  attr_accessor :firstname, :lastname

  def fullname

  end
end
如果您现在运行测试,您将从fullname返回nil。因此,我们将实现fullname方法。这里需要注意的一点是,消息已经改变,而不是Ruby抱怨缺少方法,测试抱怨我们没有正确地实现这些方法

def fullname
   return @firstname + " " + @lastname
end
现在你的考试会通过的


基本上,您希望更改测试运行后显示的消息(这将证明您正在取得进展),或者希望使其通过。测试通过后,您可以重构。上面的方法很简单,但您可以删除return语句,使用字符串格式或其他任何方法。只要测试通过,您就知道可以继续了。

在这些情况下,测试代码崩溃是可以的。把它看成是一个失败。

在实际代码之前编写测试代码将使您能够在实际开始实现该类之前设计被测试类的接口。您将有一个类用法的示例,非常好


在此之后,您将需要在测试中创建实际的类,测试将失败,而不是崩溃。然后让这个测试通过,重构并继续编写失败的测试。

我的方法是使用
该测试的条件检查
p.fullname.nil?
,或者简单地将
assert\u not\u nil(p.fullname)
作为前一个测试,当失败时将阻止其余测试执行。

如果定义了p.fullname,为什么不尝试测试呢?我想可能是这样的,我在玩弄这种语法:p=Person.new;方法=%q{name firstname fullname};methods.each{| method | assert p.respond_to?method}。人们通常是这样做的吗?@MikeyHogarth我建议您通过示例了解Kent Beck的测试驱动开发。虽然它使用Java,但本书中的概念适用于任何语言。它被认为是TDD的“Hello World”一书。我怀疑这可能是在编写虚拟方法时发生的——我会花一点时间看看是否有人提出了其他的想法。正如我所说,我的Ruby/Rails很弱,但Corey Haines对如何从Ruby代码中提取Rails混乱进行了很好的讨论。值得一提的是,如果上述模型依赖于ActiveRecord,那么您可能需要稍微改变一下方法。见@buruzaemon-好地方。这就是结对编程有效的原因;)这仍然会导致NoMethod运行时崩溃,这正是我试图避免的,因为我们的建议让我走上了正确的方向——我编辑了OP以显示我最终的结果doing@MikeyHogarth虽然这帮了你。这不是TDD,事实上这是一种相当可怕的方式。你不需要编写自定义逻辑来决定你需要断言什么。好吧,芬格拉斯,我在读了一点之后,转而回答你的问题+1碰撞试验是失败的试验。你做得很好。TDD要求您首先编写测试。