Ruby on Rails-为什么要使用测试?

时间:2020-03-06 14:39:29  来源:igfitidea点击:

我对Ruby on Rails中的各种测试设备的用途感到困惑。我已经使用该框架大约6个月了,但是我从来没有理解它的测试部分。我使用过的唯一测试是Java中的JUnit3,而且只是简要介绍一下。

我读到的所有内容都显示了测试验证。 Rails中的验证不应该起作用吗?似乎更像测试框架而不是测试代码。为什么需要测试验证?

此外,对于代码中的任何更改,测试似乎都非常脆弱。因此,如果我们更改模型中的任何内容,则必须更改测试和夹具以使其匹配。这不违反DRY原则吗?

第三,编写测试代码似乎要花费很多时间。那是正常的吗?刷新浏览器并查看其是否会更快吗?我已经必须使用我的应用程序来查看它是否正确流动,并确保我的CSS没有爆炸。为什么手动测试还不够?

我之前已经问过这些问题,而且我所获得的不只是"自动化测试是自动化的"。我足够聪明地弄清楚了自动化任务的好处。我的问题是,与收益相比,编写测试的成本似乎高得离谱。就是说,欢迎我们提供任何详细的答复,因为我可能错过了一两个好处。

解决方案

我并没有真正使用过Rails,但是我认为这些自动化测试作为烟雾测试非常有用,以确保我们刚刚做的事情不会破坏我们上周所做的事情。随着项目的发展,这将变得越来越重要。

另外,在编写代码之前编写测试(使用Test-Driven-Development模型)将有助于我们更好,更快地编写代码,因为测试迫使我们彻底思考问题。它还将了解将复杂的方法分解为可以单独测试的较小方法的位置。

没错,编写和维护测试会花费很多时间。有时比代码本身要花更多的时间。但是,由于上述原因,它可以节省错误修复和重构时间。

测试应验证应用程序逻辑。就我个人而言,我认为最重要的测试是我在Selenium中进行的测试。他们检查浏览器中显示的内容是否确实是我期望看到的内容。但是,如果仅此而已,那么我将很难调试它,它也有助于进行低级测试,并且集成,功能和单元测试都是有用的工具。单元测试使我们可以检查模型是否按照预期的方式运行(这意味着每种方法,而不仅仅是validatins)。 Validatins当然可以正常工作,但前提是我们必须正确使用它们。如果我们弄错了它们,它们将可以正常工作,而不是我们期望的那样。编写几行测试比稍后进行调试要快。

一个简单的示例(如http://wiseheartdesign.com/2006/01/16/testing-rails-validations上的示例)仅检查单元测试中的验证。 http://www.oreillynet.com/pub/a/ruby/2007/06/07/rails-testing-not-just-for-the-paranoid.html?page=1上的O'Reilly文章有点更完整(尽管仍然很基本)。

自动化测试在回归测试中特别有用,在回归测试中,我们可以更改某些内容并运行一系列测试以检查是否没有破坏其他任何内容。

测试是重复的一种形式,但是它们不违反DRY,因为它们以不同的方式表达事物。一个测试说"我做了X,所以应该发生Y"。代码说" X发生了,所以现在我需要做Z,这恰巧导致Y发生"。也就是说,测试会激发原因并检查结果,而代码会响应原因并影响某些事情。

Shouldn't
  the validations in rails just work? It
  seems more like testing the framework
  than testing the your code. Why would
  you need to test validations?

Rails中的验证确实可以工作-实际上,Rails代码库中有单元测试来确保这一点。在测试模型的验证时,我们正在测试验证的细节:长度,可接受的值等。我们要确保代码按预期编写。一些验证是简单的助手,我们可能选择不对"没有人可以弄乱" validates_numericality_of"调用"的概念进行测试。真的吗?每个开发人员是否都始终记得首先编写它?是否每个开发人员都不会意外删除错误的复制粘贴上的行?以我个人的观点,我们不需要测试Rails验证助手的所有最后一个值组合,但是我们需要一行代码来测试传递正确的值,以防将来某些朋克对其进行更改没有适当的深思熟虑。

此外,其他验证更为复杂,需要大量的自定义代码-它们可能需要进行更彻底的测试。

Furthermore, the tests seem super
  fragile to any change in your code. So
  if you change anything in your models,
  you have to change your tests and
  fixtures to match. Doesn't this
  violate the DRY principle?

我不认为它违反了DRY。他们正在交流(这就是编程,即交流)两个截然不同的事物。测试表明该代码应该执行某些操作。该代码说明了它的实际作用。当这些事物之间存在脱节时,测试就非常重要。

测试代码和应用程​​序代码紧密地联系在一起。我认为它们是硬币的两个方面。我们不会想要没有背面的正面,也不会想要没有正面的背面。好的测试代码可以增强好的应用程序代码,反之亦然。两者一起用于了解我们要解决的整个问题。编写得很好的测试代码是文档-它显示了应如何使用应用程序代码。

Third, writing test code seems to take
  alot of time. Is that normal? Wouldn't
  it just be faster to refresh my
  browser and see if it worked? I
  already have to play with my
  application just to see if it flows
  correctly and make sure my CSS hasn't
  exploded. Why wouldn't manual testing
  be enough?

我们只从事过很小的项目,对于这些项目来说,测试可以说足够了。但是,当我们与多个开发人员,成千上万的代码行,与Web服务的集成点,第三方库,多个数据库,数月的开发和需求变更等一起工作时,还有很多其他影响因素。仅仅进行手动测试是远远不够的。在任何真正复杂的项目中,一个地方的变更通常会在其他地方带来无法预料的结果。适当的体系结构有助于缓解此问题,但是自动测试也可以通过识别某个地方的变更何时破坏另一地方来帮助(并帮助确定可以改进体系结构的点)。

My problem is that
  costs of writing tests seem absurdly
  high compared to the benefits. That
  said, any detailed response is welcome
  because I probably missed a benefit or
  two.

我将列出更多好处。

如果我们先进行测试(测试驱动开发),那么代码可能会更好。我还没有遇到一个程序员,但事实并非如此。首先进行测试会迫使我们考虑问题并实际设计解决方案,而不是破解它。此外,它迫使我们充分了解问题域,以至于如果确实需要破解它,则知道代码在定义的限制范围内可以工作。

如果我们具有完整的测试覆盖范围,则可以无风险进行重构。如果软件问题非常复杂(同样,持续数月的现实世界项目往往很复杂),那么我们可能希望简化以前编写的代码。因此,我们可以编写新代码来替换旧代码,并且如果它通过了所有测试,那么我们就可以完成。它确实执行了旧代码针对测试所做的工作。对于计划使用敏捷开发方法的项目,重构是绝对必要的。总是需要进行更改。

综上所述,自动化测试,尤其是测试驱动的开发,基本上是一种管理软件开发复杂性的方法。如果项目不是很复杂,那么成本可能会超过收益(尽管我对此表示怀疑)。但是,现实世界中的项目往往非常复杂,测试和TDD的结果不言而喻:它们是有效的。

(如果我们感到好奇,我会发现Dan North在"行为驱动开发"上的文章对于理解测试中的许多价值非常有帮助:http://dannorth.net/introducing-bdd)

例如:
我从事25000多个线路项目的工作(是的,在Rails 1.2中),上周一我被告知是否可以使Users从除管理员列表之外的所有列表中消失,如果他们的" leave_date"属性设置为过去。

我们可以重写每个列表操作(超过50个)以放置一个

@ users.reject!{| u | Date.today> u.leave_date}

或者,我们可以重写" find"方法(DRY ;-),但是只有在我们进行了测试(在所有可以找到用户的东西上!)时,我们才知道我们没有通过覆盖User#find破坏任何东西!

Everything I've read about it just shows testing validations. Shouldn't the validations in rails just work? It seems more like testing the framework than testing the your code. Why would you need to test validations?

有一个很好的Railscast展示了一种测试控制器的方法。

Rails生成器创建的许多测试教程和示例测试都相当la脚和恕我直言,它们会给人一种错误的印象,即我们应该测试愚蠢的东西,例如内置的Rails方法等。

由于Rails拥有自己的测试套件,因此编写或者运行仅测试内置Rails功能的测试没有任何意义。测试应使用我们正在编写的代码! :-)

至于运行测试与仅在浏览器中进行刷新的相对优点。应用程序越大,必须手动在众多方案和边缘情况下运行以确保应用程序中没有内容的麻烦就越大坏了。最终,我们将在每次更改后停止测试整个应用程序,而只是开始"现场测试"我们认为应该受影响的区域。不可避免地,我们会发现几个月前可以正常工作的东西现在已经完全损坏了,我们无法确定它何时破裂或者发生了哪些更改。在发生足够的时间之后...我们将重视自动化测试.... :-)