<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>flypiggys (Gavin)</title>
    <link>https://ruby-china.org/flypiggys</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>[北京] 机器之心招聘前后端工程师</title>
      <description>&lt;h2 id="关于我们"&gt;关于我们&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;机器之心 Synced 创立于 2014 年，是国内首家系统性关注人工智能的科技媒体。&lt;/strong&gt;
机器之心在全球人工智能重点区域均部署有专职技术分析师、行业分析师和顾问团队，输出原创技术分析文章与产业分析报告，关注全球人工智能行业一手新闻报道。
2015 年 9 月机器之心获得数百万元的天使轮投资，2017 年 2 月获 Pre-A 轮融资，投资方包括联想之星、今日头条、源码资本、讯飞产业投资和晨兴资本等。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;工作地点：酒仙桥电子城科技园 A2 一层&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="ruby 开发工程师"&gt;ruby 开发工程师&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;岗位职责：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;基于 Web 的业务系统的设计与实现、改进与维护&lt;/li&gt;
&lt;li&gt;新技术的研究与应用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;基本要求：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;具备扎实的计算机，网络，数据库，算法基础知识&lt;/li&gt;
&lt;li&gt;拥有实际 ruby on rails 开发经验&lt;/li&gt;
&lt;li&gt;有基本的前端知识，包括 HTML, CSS, Javascript 等&lt;/li&gt;
&lt;li&gt;良好的编码习惯，对代码的简洁和美有追求&lt;/li&gt;
&lt;li&gt;对产品有 sense，理解并钻研业务背后的逻辑&lt;/li&gt;
&lt;li&gt;写测试并不把测试当做无意义的负担&lt;/li&gt;
&lt;li&gt;英文阅读以及快速学习能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前端工程师"&gt;前端工程师&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;岗位职责：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;基于 Web 的业务系统的设计与实现、改进与维护&lt;/li&gt;
&lt;li&gt;前端架构模块化，前端控件的编写与维护&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;基本要求：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;前端架构经验，能为产品制定合适的前端架构与规范&lt;/li&gt;
&lt;li&gt;有丰富的前端模块化的经验，维护过模块化的前端 UI 组件&lt;/li&gt;
&lt;li&gt;有一定的设计功底，对好的产品设计、视觉设计、交互设计有自己的见解&lt;/li&gt;
&lt;li&gt;掌握 webpack, react, vuejs, graphql&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="其它"&gt;其它&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;薪资：初级 6-10k，中级 12-18k&lt;/li&gt;
&lt;li&gt;其它待遇：我们崇尚工程师文化，尽量让工程师开心舒服的写代码，基础待遇之外有什么需求都可以提出来，尽量满足。&lt;/li&gt;
&lt;li&gt;任职需求中没有 AI 相关技能要求，但是希望你对该方面技能感兴趣。
&lt;img src="https://l.ruby-china.com/photo/2017/4860b770-6bab-449a-b643-4271683d4d92.jpg!large" title="" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="联系方式"&gt;联系方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;简历发送至 ligan@jiqizhixin.com&lt;/li&gt;
&lt;li&gt;尽量多的附上能展现你的优势和特点的代码，资料，账号等。我希望尽可能多的了解您。&lt;/li&gt;
&lt;li&gt;最长一周内回复（我会很认真的对待每一次面试，不会贸然叫您来面试，所以需要一些时间来评估是否值得让您老远跑一趟。）&lt;/li&gt;
&lt;li&gt;面试赠送机器之心周边纪念品&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>flypiggys</author>
      <pubDate>Mon, 19 Jun 2017 14:58:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/33260</link>
      <guid>https://ruby-china.org/topics/33260</guid>
    </item>
    <item>
      <title>[北京] 极客公园招聘 Ruby 工程师一名 (20k)</title>
      <description>&lt;h2 id="关于极客公园"&gt;关于极客公园&lt;/h2&gt;
&lt;p&gt;公司的介绍啊福利什么的我就不过多赘述了。相信如果你对这个职位有意思也会自己去寻找答案，也可以参考我&lt;a href="https://ruby-china.org/topics/24213" title=""&gt;以前的招聘贴&lt;/a&gt;.
团队目前主要的技术栈为 ruby on rails, 前端为 react, 移动端为 swift 原生开发.
团队的一些开源的代码可以从 &lt;a href="https://github.com/GeekPark" rel="nofollow" target="_blank" title=""&gt;github&lt;/a&gt; 参考.
目前主要有三个 rails 为后端的项目，正在用 rails5 重构之前的主站代码。&lt;/p&gt;
&lt;h2 id="岗位描述"&gt;岗位描述&lt;/h2&gt;
&lt;p&gt;这个招聘贴主要是为了招一名优秀的工程师来取代我的工作。但不需要负责繁杂的管理工作。
负责后端开发，把控代码质量，并能帮助小伙伴们一起提高。工作压力不是很大，可以尝试一些比较激进的技术。希望你能够无论从经验，视野还是代码质量上给技术团队带来更多更优秀的基因。
薪资大概表示了我对岗位水平的期望，如果和您的期待稍有偏差我们也可以聊一聊。&lt;/p&gt;
&lt;h2 id="成员介绍"&gt;成员介绍&lt;/h2&gt;
&lt;p&gt;我认为选择一份工作最大的吸引是一起工作的人。如果你加入我们，会有几个非常优秀的小伙伴等着你。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; 两个前端，目前我所共事过最优秀的前端大神，其中一个甚至只有 94 年出生，代码效率极高，并且很优雅。同样喜欢新技术，目前没有遇到过他解决不了的问题，真正的以写代码为乐趣。&lt;a href="https://github.com/liyaodong" rel="nofollow" target="_blank" title=""&gt;他的 github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  一个后端，非常聪明也非常踏实，极客公园的 iOSapp 就是他从 0 开始开发出来的。今后的日子他会更加 focus 在后端上，也希望你能够帮助他更快的提高。&lt;/li&gt;
&lt;li&gt;  两个优秀的产品经理，讲究逻辑，不瞎折腾。由于 rails 的高效，一个产品经理已经满足不了我们了所以有两个。&lt;/li&gt;
&lt;li&gt;  其它的技术团队，公园还有另外的技术团队，主要使用 nodejs 以及 python, 上面的几个是你朝夕相处的人，其它团队也可以和你产生更多的火花。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="任职要求"&gt;任职要求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt; 一年以上 rails 开发经验，如果你是一个能力优秀的人，我相信一年的经验已足够你写出优秀的 rails 代码。&lt;/li&gt;
&lt;li&gt; 跟上 rails 的更新步伐，关注每个 ruby 以及 rails 版本更新的区别。起码知道并用过单身狗运算符😂😂😂&lt;/li&gt;
&lt;li&gt; 订阅并阅读每期的 ruby weekly 等，观看每次国外高质量大会的视频并有心得。&lt;/li&gt;
&lt;li&gt; 善于分享，爱折腾，喜欢看 github trending. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="其它"&gt;其它&lt;/h2&gt;
&lt;p&gt;发送简历到 ligan#geekpark.net，并最好在邮件里附上你的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog/GitHub/Stack Overflow 等&lt;/li&gt;
&lt;li&gt;GitHub 不要空白，我希望能通过代码能够更多的了解您。一个有说服力的 github 能够节省掉您做题的时间。&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>flypiggys</author>
      <pubDate>Mon, 01 Aug 2016 15:20:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/30687</link>
      <guid>https://ruby-china.org/topics/30687</guid>
    </item>
    <item>
      <title>一个简单的评论过滤系统的实现</title>
      <description>&lt;p&gt;最近公园网站开启匿名评论之后，垃圾评论就一直是一个让人头疼的问题。关键词过滤及限制评论数很容易被找到针对的办法，发垃圾评论的人会不停的通过空格，符号等来绕过关键词的过滤。对于一个每天评论不过百的网站来说，上 &lt;a href="http://en.wikipedia.org/wiki/Natural_language_processing" rel="nofollow" target="_blank" title=""&gt;NLP&lt;/a&gt; 又太重了 (其实是不懂).&lt;/p&gt;
&lt;h2 id="通过语句相似度过滤垃圾评论"&gt;通过语句相似度过滤垃圾评论&lt;/h2&gt;
&lt;p&gt;后来我想到公园网站的垃圾评论大部分内容都是几个垃圾评论的变种，内容的相似度都比较高。所以我只需要维护一个包含这几个内容的列表，并计算语句的相似度，屏蔽掉相似度较高的评论就可以暂时达到过滤垃圾评论的目的。&lt;/p&gt;

&lt;p&gt;研究如何计算过程中我找到了 2 种方式，&lt;a href="http://en.wikipedia.org/wiki/Levenshtein_distance" rel="nofollow" target="_blank" title=""&gt;Levenshtein distance&lt;/a&gt; 以及 &lt;a href="http://www.catalysoft.com/articles/StrikeAMatch.html" rel="nofollow" target="_blank" title=""&gt;How to Strike a Match&lt;/a&gt; . 最后我使用了后者计算相似度的方式实现了一个简单的评论过滤系统。&lt;/p&gt;
&lt;h2 id="代码实现"&gt;代码实现&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/threedaymonk/text" rel="nofollow" target="_blank" title=""&gt;text&lt;/a&gt;这个 gem 同时提供了以上两种算法。有兴趣的可以看一下源码中两种算法的具体实现。&lt;/p&gt;

&lt;p&gt;Comment 中验证评论是否合法&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="ss"&gt;:check_spam&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_spam&lt;/span&gt;
    &lt;span class="c1"&gt;#遍历检查 spam 中条目与评论的相似度, 如果大于设定比例则添加 error, 验证失败&lt;/span&gt;
    &lt;span class="no"&gt;Spam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;spam&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WhiteSimilarity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"内容不合法"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="c1"&gt;# 对于 spam 中没有收录的模板或漏网之鱼的新评论检查与最近的3条评论的相似度&lt;/span&gt;
    &lt;span class="c1"&gt;# 如果相似度大于95%则过滤, 一般垃圾评论都是连续刷评论的.&lt;/span&gt;
    &lt;span class="n"&gt;new_record?&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="no"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WhiteSimilarity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"内容不合法"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加上这层防护之后，应该可以暂时安心了。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.ligan.me/2015/01/13/a-simple-comments-spam-system/" rel="nofollow" target="_blank" title=""&gt;原文连接&lt;/a&gt;&lt;/p&gt;</description>
      <author>flypiggys</author>
      <pubDate>Wed, 14 Jan 2015 01:03:02 +0800</pubDate>
      <link>https://ruby-china.org/topics/23718</link>
      <guid>https://ruby-china.org/topics/23718</guid>
    </item>
    <item>
      <title>RubyConf 吐槽贴</title>
      <description>&lt;p&gt;首先感谢姜军和各位组织者辛苦为我们组织了这次大会，开贴只为吐槽不为攻击&lt;/p&gt;

&lt;p&gt;广告时间没把握好，如果不限制都希望多说点，体验就很差。&lt;/p&gt;

&lt;p&gt;希望讲师多讲点干货，首先把大家放在 ruby 工程师的角色上，少讲点大家都懂的东西，有实际操作经验更好了，植入广告隐蔽点&lt;/p&gt;

&lt;p&gt;我看到 ruby 和 java 代码比较那里真的想吐槽了，毕竟不是到 pyconf 去讲 ruby。&lt;/p&gt;</description>
      <author>flypiggys</author>
      <pubDate>Sat, 01 Nov 2014 10:01:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/22394</link>
      <guid>https://ruby-china.org/topics/22394</guid>
    </item>
    <item>
      <title>使用 feature Spec 编写用户 / 验收测试</title>
      <description>&lt;p&gt;&lt;strong&gt;feature spec 与 request spec 的区别&lt;/strong&gt;
rspec 和 capybara 在 ruby 程序员中很多人都不陌生了。在 2.0 版本以后的 capybara 中，新加入了 feature spec 的写法。在 rspec 中默认使用 spec/feature，而不再使用 spec/request.&lt;/p&gt;

&lt;p&gt;feature spec 在测试中来说是比较高等级的测试。大概相当于集成测试或者更高级别的用户/验收测试。一般是模拟用户的实际操作和应用外部的请求来执行测试.简单来说就是模拟浏览器中的动作，期待应用正确的反应。&lt;/p&gt;

&lt;p&gt;为什么 2.0 之后的 capybara 要做出这样的改动呢？&lt;/p&gt;

&lt;p&gt;因为一般的来说 capybara 是模拟浏览器中的动作，这种测试是相当于模拟一个用户在用户界面中的操作，是基于 usercase 的。而以前的 request spec 则还是没有脱离应用层面 (发送 http 请求，比较相应结果),比如在以前的 capybara 的 dsl 中，使用'get'来访问页面，而现在则改成了'visit'.后者'访问'这个动作，比'get'这个 http 请求更接近于用户的行为。&lt;/p&gt;

&lt;p&gt;所以使用 feature spec 相对来说更符合 behavior 的思想，也带来更好的阅读性。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rails 中使用 feature spec&lt;/strong&gt;
本文以 rails 为例，来介绍 feature spec 的使用。&lt;/p&gt;

&lt;p&gt;首先安装 rspec 和 capybara，在 gemfile 中加入&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:development&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rspec-rails'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'capybara'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后执行&lt;/p&gt;

&lt;p&gt;bundle install&lt;/p&gt;

&lt;p&gt;再之后执行&lt;/p&gt;

&lt;p&gt;rails generate rspec:install&lt;/p&gt;

&lt;p&gt;rspec 和 capybara 就安装完毕了。&lt;/p&gt;

&lt;p&gt;rails 中的 generator 默认生成的集成测试会在 request/xxxx_spec.rb.默认是不支持 capybara 的，我们如果要在其中使用 capybara 还要在 spec_helper 中的 configure 中加入&lt;code&gt;config.include Capybara::DSL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;而我们要使用的 feature/xxxx_spec.rb 目前尚无法由 rails 自动生成，但是不用做任何设置就可以支持 capybara 的 DSL.&lt;/p&gt;

&lt;p&gt;所以我们手动建立 spec/feature 文件夹，在其中手动创建 XXXX_spec.rb 的测试文件。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;feature spec 写法&lt;/strong&gt;
在 feature spec 中，我们使用&lt;code&gt;feature - scenario&lt;/code&gt; 来替代之前 rspec 的&lt;code&gt;describe - it&lt;/code&gt;模式
注意两者千万不要混写成&lt;code&gt;feature - it&lt;/code&gt;或者&lt;code&gt;describe - scenario&lt;/code&gt;这种不伦不类的风格..&lt;/p&gt;

&lt;p&gt;另外与 describe 不同，feature 下面是不允许再套 feature 的。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"Static pages"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"Home page"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"should have the content 'Sample App'"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/static_pages/home'&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Sample App'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样是可以的，但是把 describe 换成 feature 则会报错。&lt;/p&gt;

&lt;p&gt;feature spec 的测试中，我们一般按照待测的功能点来划分用例，即每一个 feature.而每一个 scenario 对应一条 user case.这一点和测试人员写测试用例的方法很相似。比如下面的 2 条测试用例&lt;/p&gt;

&lt;p&gt;功能点                      用户输入         期望结果
用户登录    用户输入正确的用户名和密码 登录成功
                用户输入错误的用户名和密码 登录失败&lt;/p&gt;

&lt;p&gt;使用 feature spec 的方式写出的测试代码如下。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"spec_helper"&lt;/span&gt;

&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s2"&gt;"Login"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s2"&gt;"User enter right account"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/login"&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:with&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"username"&lt;/span&gt;
    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:with&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"right"&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"login"&lt;/span&gt;

    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;have_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"welcome back,username"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s2"&gt;"User enter wrong account"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/login"&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:with&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"username"&lt;/span&gt;
    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:with&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"wrong"&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"login"&lt;/span&gt;

    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;have_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Wrong password,please try again!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;feature spec 的简单介绍就写到这里，希望大家喜欢这种方式。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.ligan.me/blog/2013/09/08/rspec-feature-ce-shi-jian-jie/" rel="nofollow" target="_blank" title=""&gt;source&lt;/a&gt;&lt;/p&gt;</description>
      <author>flypiggys</author>
      <pubDate>Sun, 08 Sep 2013 21:45:30 +0800</pubDate>
      <link>https://ruby-china.org/topics/13971</link>
      <guid>https://ruby-china.org/topics/13971</guid>
    </item>
    <item>
      <title>有人在 coursera 上面刷课么～</title>
      <description>&lt;p&gt;最近开始上 coursera 上刷课玩，学的第一门
&lt;a href="https://www.coursera.org/course/proglang" rel="nofollow" target="_blank" title=""&gt;programming languages&lt;/a&gt;
感觉就是神课~学了以后受益匪浅..跟大家推荐下~&lt;/p&gt;</description>
      <author>flypiggys</author>
      <pubDate>Mon, 21 Jan 2013 16:07:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/8234</link>
      <guid>https://ruby-china.org/topics/8234</guid>
    </item>
    <item>
      <title>使用 rails 的 migration 怎样将一个表中数据复制到另一个表</title>
      <description>&lt;p&gt;将 product 中的 price 复制到 line_item 中，我是这样写的。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddPriceToLineItem&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:decimal&lt;/span&gt;
    &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是实际中发现 li.price 是得到了值的&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt;   &lt;span class="c1"&gt;#&amp;lt;BigDecimal:99ca80c,'0.4375E2',18(45)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是 line_items 表中却没有数据&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="c1"&gt;#&amp;lt;LineItem id: 4, product_id: 2, cart_id: 3, created_at: "2012-09-15 17:48:50", updated_at: "2012-09-15 17:48:50", quantity: 1, price: nil&amp;gt;, #&amp;lt;LineItem id: 5, product_id: 3, cart_id: 3, created_at: "2012-09-15 17:48:55", updated_at: "2012-09-15 17:48:55", quantity: 1, price: nil&amp;gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请问是何原因，如果想通过 migrate 复制表中的数据正确应该如何写？&lt;/p&gt;</description>
      <author>flypiggys</author>
      <pubDate>Sun, 16 Sep 2012 13:50:05 +0800</pubDate>
      <link>https://ruby-china.org/topics/5565</link>
      <guid>https://ruby-china.org/topics/5565</guid>
    </item>
  </channel>
</rss>
