测试 对于测试经常会提起的问题

saberma · 2013年07月14日 · 最后由 luikore 回复于 2013年07月14日 · 4013 次阅读

昨天参加深圳 Rubyist 聚会分享了《Rails 项目测试》。

Slide 在这里:http://yafeilee.me/RailsTest.pdf

在聚会期间有些朋友提到了一些测试相关的问题,整理如下:

我的项目一直都没时间写测试,又觉得测试很重要,怎么办?

如果觉得项目很紧很紧,可以分以下几个测试级别来考虑: 只写 Feature 测试覆盖正常流程,忽略各种单元测试 这样起码可以保证正常流程是不容易被破坏的。

如果做不到, 就只针对 Bug 写测试 。 出现 Bug 后,先编写测试用例重现 Bug,再进行修正。 这样可以保证以后这个 Bug 不会重现。

如果这个也无法做到,可以再退一步, 保证错误发生时,你能立即得到通知 ,减少错误的影响面。 可以使用 Exception Notification 来得到错误通知邮件。

测试需要占用多少时间?

熟悉测试之后,其实占用不了多少时间,写一个 Feature 测试也就几分钟的事情。

测试的内容也非常简单,就是两个方面:

  1. 行为,要做什么
  2. 匹配,对不对

这两方面占用的时间很少,反而是在此之前的数据准备占用的时间更多。 不过如果使用新版本的 Factory_Girl,有了 trait 特性,这方面也花不了多少时间。

Controller 测试和 Feature 测试功能都差不多,如何避免重复写测试代码?

这个要区分出不同测试类型的测试侧重点。 Model 测试侧重于与数据库相关的测试,包括与之相关的异常流程(校验不通过)。例如:

  • 测试 User.save 方法调用后,User 表会增加一条记录;
  • 测试 Email 唯一性,不为空等。

Controller 测试侧重于页面的交互,例如:

  • 测试 create 方法被调用后,有没有正常 redirect_to
  • 测试 index 方法被调用后,有没有正常设置 @users 变量,以供视图层使用
  • 测试 create 方法调用前,用户一定需要登录

Feature 测试侧重于跨多个 Controller 或者 action 的功能测试,例如:

  • 测试发贴后直接回贴,成功后看到提示信息

再具体点说明。

Controller 测试和 Model 测试如何避免重复? 例如:UserController 中的 create 调用后,我们当然可以测试 User 表有没有增加一条记录。但这就会导致与 Model 测试重复了。根据侧重点原则就知道要把这些测试移至 Model

Feature 测试和 Controller 测试如何避免重复? 例如,开发了注册用户功能后,先使用 Feature 测试注册成功;但是这个功能除了注册成功外,还有注册失败的流程,对于这个功能也可以使用 Feature 来进行测试,但为了避免重复,对于这样的异常流程尽量移到 Controller 测试。

总的来说,Feature 测试是最重要的,当我们开发完功能,手工测试一遍后,这个过程步骤一定要编写成 Feature 测试,由于 Feature 测试会模拟浏览器的行为,属于重型测试(时间较长)。所以尽量使用 Feature 来保证正常流程(注册成功),将异常流程(校验不通过注册失败)移到 Controller 测试或者 Model 测试。

是否一定要 TDD?

我在测试过程一半时间会 TDD,其他则是事后补 Feature 测试。

具体分两个层面来看: 单元测试这一层,例如在 Controller, Model, Helper 等增加额外的方法,会 TDD。 而对于功能测试这一层,在创业项目中,有些功能高度不确定,得边想边做边完善,这种情况做 TDD 会花费更多的时间。

以前对 TDD 不怎么感冒,现在写程序很自然而然就 TDD 了

默默地点一下喜欢

* 测试 User.save 方法调用后,User 表会增加一条记录; 这个也需要测试吗?你除了调用 save 方法,没写别的 code,那就是在测试 save 方法?这应该是 rails 标准测试的一部分吧,

@loveky 测试 User 上加的 validate、callback

#3 楼 @kimigao1986 validate 的测试我都是用 shoulda-matcher 写的,所以没有明确用过 save 来测试。 callback 的话,你是说 callback 有可能会阻止对象成功 save 是吧?

那么一些 js 层面的如何进行测试,比如 angularjs 做的一些逻辑代码

很有参考价值。赞。

建议两个阶段,前期功能不稳定,就不要测试。二阶段基本稳定了,可以考虑测试。

其次,测试范围可大可小。时间不够可考虑关键点测试。

TDD 是个重要的东西,不过具体怎么用还没有一致的说法。

#2 楼 @loveky 不是必要的,这里更多的是举例说明的作用。

对于 Rails 或者其他框架标准化的方法是可以不用测试的,除非是考虑到数据库 null 值限制之类的东西会影响 save

#5 楼 @sanivbyfish JS 层面的测试可以使用 Jasmine,如果使用 AngularJS 就更方便了,原生的 JS 视图层和逻辑控制器分离,只要测试控制层就可以了。

这方面的内容在现场有结合 19 屋的实际例子进行讲解,你可以看看 spec/javascripts 中的内容。

增加 测试需要占用多少时间? 问题

粗略的说

写测试只是 2 倍时间,不写要花 10 倍时间 debug ...

需要 登录 后方可回复, 如果你还没有账号请 注册新账号