`
java-admin
  • 浏览: 1376431 次
  • 性别: Icon_minigender_1
  • 来自: 陕西.西安
社区版块
存档分类
最新评论

使用 RSpec 进行行为驱动测试,配置分析

 
阅读更多

http://huangzhimin.com/

 

<!-- AddThis Button BEGIN --> <script src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=flyerhzm" type="text/javascript"></script><!-- AddThis Button END -->

after_commit

We are using RabbitMQ as our message queue system, ruby client is workling. This week we encountered a strange issue, we create a notification, and define an after_create callback to ask workling to find that notification and then push the notification to twitter or facebook, it works fine except that sometimes it will raise an error said "can't find the notification with the specified ID"

class Notification < ActiveRecord::Base
  after_create :asyns_send_notification
  ......
  def async_send_notification
    NotificationWorker.async_send_notification({:notification_id => id})
  end
end

class NotificationWorker < Workling::Base
  def send_notification(params)
    notification = Notification.find(params[:notification_id])
    ......
  end
end

It's wierd the notification_id is passed to NotificationWorker, that means the notification is already created, the notification is supposed to be existed.

After talking with MySQL DBA, we find the problem is the find sql is executed before insert transaction is committed.

Let me describe it step by step.

  1. Notification sends "Transaction Begin" command
  2. Notification sends "INSERT" command
  3. Notification gets "next sequence value" as new object id
  4. Notification sends "new object id" to NotificationWorker
  5. NotificationWorker sends "SELECT" command to find notification object
  6. Notification sends "Transaction Commit" command

As you seen, at step 5, the new notification is not existed in the mysql database yet, so the error "Not found" will be raised.

To solve this issue, we can use after_commit callback.

In rails 2.x, we should install after_commit gem, in rails 3.x, after_commit callback is supported by default.

class Notification < ActiveRecord::Base
  after_commit_on_create :asyns_send_notification
  ......
  def async_send_notification
    NotificationWorker.async_send_notification({:notification_id => id})
  end
end

So Notification asks NotificationWorker to run only after the transaction is committed.

Posted in  Rails


reset_counter in rails

I thought reset_counter method is to reset a counter_cache column to be 0, but it is not. After trying several times, I finally realize that reset_counter is to update the value of counter_cache column to the exact count of associations. The usecase of reset_counter is when you add the counter_cache in migration and update the counter_cache value, like

def self.up
  add_column :posts, :comments_count
  Post.all.each do |post|
    Post.reset_counter(post.id, :comments)
  end
end

it will add comments_count column to posts table, and calculate the comments count for each post, and set it to posts' comments_count column.

I didn't find a method to reset the counter_cache column to be 0, why? Because counter_cache is used to cache the association count, it will be incremented and decremeneted automatically, you should never reset it 0. If you find you need to reset counter_cache to 0, that means it's a wrong usage of counter_cache.

Posted in  Rails


use rspec filter to speed up tests

Rspec 2 introduce a very efficient way to test only one test or one test suit, it's filter_run.

You should first add filter_run in rspec/spec_helper.rb

config.filter_run :focus => true

Then you can tell rspec to test only one test you are focused by

it "should focus now", :focus => true do
  ...
end

rspec will only test this spec, :focus => true can be applied on describe/context as well.

One problem is that if there is no :focus => true on your tests, rspec will do nothing, but most of time we are expecting to test all specs if no focus is true, so you should add a line to spec_helper as well.

config.run_all_when_everything_filtered = true

As the name implies, rspec will test all specs if no focus filter.

Another you may interest that you can also define filter_run_excluding

config.filter_run_excluding :slow => true

rspec will run all specs except what specs are marked as slow.

分享到:
评论

相关推荐

    使用RSpec 测试Rails 程序.pdf

    **RSpec**(RSpec is not a unit testing framework)是一种为Ruby编程语言设计的行为驱动开发(BDD)框架,而**Rails**是基于Ruby的一个全栈web应用框架。将RSpec与Rails相结合可以有效地进行单元测试、集成测试...

    RSpec 3.1中文版

    RSpec是Ruby语言开发的一款行为驱动开发(BDD)工具,它通过使用领域特定语言(DSL)来帮助开发人员编写测试用例。RSpec 3.1版本是RSpec框架的更新版,提供了更多的功能和更好的用户体验。Rails是一个用Ruby语言编写的...

    rspec 入门者学习

    RSpec 是一个流行的 Ruby 测试框架,主要用于行为驱动开发 (Behavior-Driven Development, BDD)。RSpec 的设计目的是让测试更加自然和易读,使得开发人员能够更好地理解和编写测试用例。 #### 二、RSpec 与 BDD **...

    jruby-1.5.5+OperaWatir+RSpec

    RSpec 是一个流行的 Ruby 测试框架,主要用于行为驱动开发(BDD)。它提供了一种声明式的方式来描述对象应该如何表现,以及期望的行为结果。RSpec 的语法使得测试代码更接近自然语言,让非程序员也能理解测试目的。...

    在rails中 使用RSpec生产CHM文档

    RSpec是Rails开发中的一个行为驱动开发(BDD)测试框架,用于编写可读性强、易于理解的测试代码。通过RSpec,开发者可以清晰地表述他们期望的代码行为,确保软件按预期工作。在本案例中,它可能被用来验证生成CHM...

    BDD开发之rspec和cucumber

    考虑到《RSpec Book》这本书的内容,我们可以推断其中包含了大量关于如何使用RSpec和Cucumber进行BDD开发的实际案例。书中可能包括了以下内容: - **RSpec基础知识**:介绍RSpec的基本概念、安装配置、核心特性和...

    使用Cucumber+Rspec玩转BDD(1)——用户注册

    在Ruby on Rails开发中,行为驱动开发(Behavior Driven Development, BDD)是一种常见的实践,它强调通过描述软件的行为来定义需求。Cucumber和RSpec是两个强大的BDD工具,它们一起工作可以创建清晰的测试场景,...

    rspec_demo:Rspec演示

    在Ruby编程语言中,RSpec是一种广泛使用的测试框架,它允许开发者以一种清晰、简洁的方式编写行为驱动的开发(BDD)测试。`rspec_demo`项目显然是一个展示如何使用RSpec进行测试的实例。通过这个演示,我们可以深入...

    Ruby-rspecapidocumentation从RSpec自动生成API文档

    RSpec是一个广泛使用的BDD(行为驱动开发)框架,通过编写可读性强的断言来验证代码的行为。rspec_api_documentation则将RSpec的测试用例转化为结构化的API文档,使得开发者可以更直观地了解API接口。 rspec_api_...

    rspec:Ruby 的行为驱动开发框架

    RSpec 是一个广受欢迎的 Ruby 语言的测试框架,专门用于实现行为驱动开发(Behavior-Driven Development, BDD)。它通过提供清晰、易读的语法来定义预期的行为,使得代码更加易于理解,并且鼓励开发者以业务需求为...

    自动化生成支持cucumber,Rspec的Rails(持续更新中)

    标题 "自动化生成支持cucumber,Rspec的Rails(持续更新中)" 暗示了这个压缩包文件的内容可能涉及使用Cucumber和RSpec这两种自动化测试工具在Ruby on Rails框架下的集成和配置。Cucumber是一种行为驱动开发(BDD)的...

    Ruby-EmojiRSpec用于RSpec的自定义Emoji格式化程序

    在Ruby开发过程中,测试是保证代码质量的重要环节,RSpec作为一款强大的行为驱动开发(BDD)测试框架,广泛应用于各种项目。而Ruby-EmojiRSpec则是在这个基础上增添了一抹独特的色彩。 首先,我们来了解一下RSpec。...

    基于Ruby的Web自动化测试框架平台应用.rar

    RSpec是Ruby的一个行为驱动测试框架,它提供了丰富的断言库和匹配器,使得编写测试变得更加简单。RSpec可以用于单元测试、集成测试以及端到端测试,确保代码的各个部分都能按预期工作。 在Web自动化测试中,通常会...

    [持续测试].(Continuous.Testing).Ben.Rady&Rod.Coffin.文字版.pdf

    例如,使用 RSpec 进行行为驱动开发(BDD),以及使用 Cucumber 进行验收测试等。 - **2.3 设置持续集成服务器** 本节将介绍如何设置持续集成服务器,如 Jenkins 或 Travis CI 等。这些服务器负责监控代码库的...

    Atom-language-rspec,atom的rspec语言包。为pauldruziak/语言做出贡献.zip

    RSpec是一种流行的Ruby行为驱动开发(BDD)框架,用于编写可读性强、表达力强的测试代码。这款插件由pauldruziak贡献,并在GitHub上进行维护和更新。 Atom是一款由GitHub开发的免费、开源文本编辑器,它基于Web技术...

    ruby+selenium-webdriver测试-测试用例源代码

    9. **测试数据驱动**:如果测试需要多组输入数据,可以使用 RSpec 的 `each` 或 `data_table` 特性,实现数据驱动测试。 10. **页面对象模式**:为提高代码可读性和可维护性,我们可以采用页面对象模式,将每个页面...

    rspec-cucumber-start:知道如何使用 Cucumber 和 rspec 测试纯 Ruby 应用程序!

    Cucumber是一个行为驱动开发(BDD)工具,它允许开发者、测试人员和非技术人员通过简洁易懂的自然语言描述来定义软件的行为。这些描述通常被称为特性文件,采用Gherkin语法编写,使得业务规则和需求能够被团队中的...

    non-rails-bdd-testing-application:此存储库是使用Capybara和Rspec的功能测试通用应用程序(无轨)的基本配置

    此存储库是使用和的功能来测试通用应用程序(无轨)的基本配置。 有时,我需要测试用非Ruby语言编写的通用Web应用程序的行为,例如Wordpress,Drupal ...此存储库提供了开始编写自己的测试的基本配置。 我使用 gem来...

Global site tag (gtag.js) - Google Analytics