测试 前端测试框架错综复杂,跟 rails 集成又是各种迷乱,求 Rails 集成测试方案

hlxwell · 2014年06月25日 · 最后由 hlxwell 回复于 2014年07月04日 · 6093 次阅读

问题篇:

市面上测试框架太错综复杂了。尤其是 Rails 程序用 angular 写了前段以后,发现以前 rails view 端的逻辑很多多挪到了 js 上去了。所以 js 的测试也变得必然了。

网上一查各种迷惑, jasmine, kama, phantomjs, protractor .... 各种名词。

然而现在所有的前段测试框架比如 jasmine + karma + phantonjs 都是完全脱离 rails 的. 意思就是 Rails 的 assets pipeline, rails 的测试数据完全用不上了。angujarjs unit test 现在唯一找到比较好的方案就是用 jasmine-rails gem, 可以用 coffeescript, headless, 以及浏览器上跑测试。在测试后端的时候,fixture data 也不能直接用到前段,必须再做一份给前端用作 api 返回结果。gon 也用不了了,要想办法用其他方法解决。有时候真相干脆用 capybara 直接继承测试搞定就好了。可是集成测试真心慢。有时候调试真心麻烦。 不知道有没有好心人介绍一下比较好用的可以在 rails 上用的前端测试最佳实践?

假想的方法:(挫了点,但是发现有人真这么做了。)

Javascript 用 phantonjs 实现一个 让前段或者测试程序员用 javascript 就能写出的测试。在测试服务器上跑一个 Rails 应用,然后通过弄一个 FixtureController 来进行数据准备,比如 /fixtures/load_users /fixtures/cleanup_database。

我觉得你现在遇到的难题应该和架构有关。

如果之前预测到 Angular 只是轻量级的使用,那么 jamine-rails 加 Capybara 加肉测应该够用了,因为前端逻辑不是很多。jasmine-rails 我之前用过,测一点点 backbone 的单元测试一点问题都没有,但复杂的前端就会觉得不够力。Capybara 我觉得尽量少用,因为太慢,而且 coupling 太高,除非是既复杂又重要的流程否则不用它。

如果预见前端有大量的逻辑,那么就最好不要使用 assets pipeline,而是前后端彻底分离,使用 Angular/Grunt 的体系来做前端的一切,包括发布、测试等等。这样的话后端直接用 request spec 或者 controller spec 测 API。简单明了。前端自己测自己的,和后端无关,拥抱一切 Angular 最佳实践比如 karma 等等。

你这个问题不是 Rails 独有的, 基本上 web 程序的测试都得这么测. 无非就是 单元测试

  • 前端 Angular -> 使用 Jasmine + Kamar + photomjs/brower
  • 后端 Rails -> 普通的单元测试

集成测试/Acceptance Test 系统在真实部署情况下的白盒测试

  • Rails 的 Restful 端测试 -> 比较简单, 无非是一些 restClient 访问而已, 需要根据 case prepare fixture
  • 集成测试, 使用 angular E2E, 或者使用更为通用的 selenium 方案

其他可选方案 随着 nodejs 和 phontomjs 的兴起, 可以使用更为简单实用的 js 来写 acceptance test case 来替代 selenium 的方案. 当然考虑到浏览器兼容性问题,还是推荐 selenium 结合几个主要的目标浏览器来跑.

测试用例特别是 acceptance test 的 cover 程度, 需要根据团队实际的 confidence/comfortable level 来确定, 否则的话是无底洞.

如果是大型 spa 应用,还是前后端分离吧。

#3 楼 @everett 前后端分离是什么概念呢?走在不同的项目里?

jasmine + karma + phantonjs 都是完全脱离 rails 的. 意思就是 Rails 的 assets pipeline, rails 的测试数据完全用不上了。

不太明白这个,举个例子?

我也碰到了这种问题。目前想来,拆成两个项目会更好,如果你有时间折腾的话。

拆开大概面临的问题是,HTML, CSS, JavaScript 全部放前端项目。也就是说 bootstrap-sass 这样的东西不需要靠 Rails 来装了。带来的问题当然就是 asset pipeline 完全用不着了,所以你得用其他的方式来做它所提供的功能:

  1. SASS 的合并,JavaScript 压缩,这个还算好办。
  2. 为压缩后的文件加 fingerprint,这个还涉及到 HTML,Node 里也有插件可以实现。
  3. SASS 文件里的 image-url ,估计也可以用 Compass 无缝过渡。

从长期来开,如果前端本来就很重,分开是个很好的选择,我觉得也是必须要走的一步。从此 Rails 可以更轻松。不需要 view 和 helper 了。测试到 Controller 层为止,不过还得加一层 Serializer ,处理 JSON 数据。

我在想一个不用完全分开的过渡方案,大概就是 CSS 和 image 还是用 Rails 的 asset pipeline,先只把 JavaScript 分离出去。目前能够想到的方案:

  1. 单独开一个目录存 JavaScript 文件,
  2. 用 Node 的工具(Grunt, Gulp, Broccolli 等)合并成一个文件,然后 copy 到 app/assets/javascripts/application.js
  3. Rails 端什么都不用改,HTML 模板里面 javascript_include_tag 'application' 就完了。
  4. 部署的时候用 Rails asset pipeline ,Rails 会自动给 application.js 加上 fingerprint。
  5. JavaScript 测试的话,单元测试完全够用了。

缺点是 application.js 需要放到版本库中去,而且每次开发需要开一个 Rails server 和一个 Grunt 任务。这个方案相当于一个半吊子前端项目(只处理 JavaScript)和 Rails 项目的整合,只是平滑过渡用。

#4 楼 @aptx4869 teaspoon is awesome. 谢谢

#7 楼 @darkbaby123 其实能完全拆成两个项目当然好。我们的项目一部分还是用 rails 的。暂时还没有拆开。就算实现一下,也要花很多功夫进去。

#1 楼 @billy 你说的对,我觉得 capybara 太慢了。每次写完跑一下测试要等一会儿。这个以前吃太多苦头了。

#6 楼 @raven 你们现在里面用了什么 js 框架没有啊?你们还是用 capybara 吗?capybara 启动慢了点,测试调试也麻烦了点。

#5 楼 @QueXuQ 可能我的说法不太好,我在 app 之外建立了 ngapp 的文件夹来存放,除了 css 以外的前端相关的代码,spa 用 karma+Jasmin+Protractor 测试, 测试环境不再依赖 rails。但是运行仍然使用 assets_pipline。在我自己的项目里面,我把前端都剥离出来放在引擎里面。穿越前后端的测试分成了纯前端测试和后台的 api 测试。

http://angular-rails.com/ 上的方案是否可行?

#11 楼 @hlxwell 依然还是 capybara 确实慢。。 前些日子在另一个项目里用了 phantomjs 感觉不错 比 capybara 快多了

#14 楼 @raven phantomjs 你看不到出错的时候的结果了,不过可以截图的说。你们试过光 integration 测试么?

#15 楼 @hlxwell 大多数时候一个截图就够了。。 什么叫光 integration 测试? 单独跑 integration ?

正好这两天也在琢磨这个事情。上网搜索了半天,找到了几个解决方案。

可以参考下这个项目:https://github.com/EmmanuelOga/simple-angular-rails-app

rails 和 angular 代码分开,开发、测试时通过 grunt-connect-proxy 插件代理访问。

这样测试也是分开的,rails 测试仍走 rspec,angular 走 karma。

不过,部署时 angular 的代码是直接放到./public 下的。

#17 楼 @zisasign 其实我最近弄了以下最后还是用了 capybara, 放弃了 protractor, capybara + phantomjs + poltergeist 足够了,数据能够准备,前段能够测到,后端也能测到,也能跑 CI

#17 楼 @zisasign 你跑 karma 还不就为了用 jasmine 写测试么,其实用 jasmine 一点意义也没有。你集成测试要跑的快,瓶颈在后端。

#19 楼 @hlxwell 我这边 Rails 主要是提供 API,跟前端逻辑分的比较清了。 反而,对于 angular 部分的测试比较多。而且 mocks 测试数据什么的,很多时候不太用和后端交互。 这个方案比较合适这种。

#20 楼 @zisasign angular unit test 其实比继承测试代码还多。 但是好处就是用浏览器测试 js 速度很快。

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