Rails:使用 cucumber 和 webrat 集成测试thinking_sphinx - 如何索引事务装置?

发布于 2024-07-21 07:09:02 字数 261 浏览 5 评论 0 原文

我想对我的搜索功能进行一些 Cucumber/webrat 集成测试,这些功能使用 Thinking_sphinx & sphinx 但问题是,在典型的 Cucumber 测试期间,数据会在事务中加载然后回滚,因此 Thinking_sphinx 无法为其建立索引。 或者,是否有办法仅针对一部分测试关闭事务?

你解决这个问题了吗?

[编辑 - 请不要建议模拟搜索结果。 我希望集成测试能够测试所有功能的集成,包括thinking_sphinx]。

I'd like to have some Cucumber/webrat integration tests of my search features that use thinking_sphinx & sphinx but the problem is that the data is loaded and then rolled back in a transaction during a typical cucumber test so there is no way for thinking_sphinx to index it. Alternatively, is there a way to turn transactions off for just a subset of tests?

Have you solved this problem?

[edit - please don't suggesting mocking out the search results. I want the integration test to test the integration of all the features including thinking_sphinx].

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梦亿 2024-07-28 07:09:02

我发现问题出在这个声明中:

在典型的 Cucumber 测试期间,数据会在事务中加载并回滚,因此 Thinking_sphinx 无法为其建立索引

Thinking_sphinx 为结果建立索引可能不会,但肯定 >可能在交易中。 由于这是一个单一的集成测试,并且没有对每个(许多)单元测试进行测试,因此我会承受速度的影响。

因此,现在您需要弄清楚如何在事务期间触发重新索引。

# somewhere in /features/support:
before('@reindexing') do
  require 'Rake'

  class MyModel
    after_save :force_reindex!

    def force_reindex!
      # in case multiple runs of this block cause the hook
      # to get added multiple times, let's check to make sure
      # we haven't already reindexed for this save
      return if @__reindexed
      Rake["thinking_sphinx:rebuild"].execute
      @__reindexed = true
    end
  end
end

after('@reindexing') do
  class MyModel
    def force_reindex!
      # do nothing; the hook still gets called, but that's ok
    end
  end
end

/features/integration.feature (或其他)中,你有

@reindexing
Feature: The whole shebang, altogether

  Scenario: ...

I see the problem being in this statement:

the data is loaded and then rolled back in a transaction during a typical cucumber test so there is no way for thinking_sphinx to index it

It may not be fast to have thinking_sphinx index the results, but it's certainly possible within the transaction. Since it's a single integration test, and not done for each of your (many) unit tests, I'd take the speed hit.

So now you need to figure out how to trigger that re-index during a transaction.

# somewhere in /features/support:
before('@reindexing') do
  require 'Rake'

  class MyModel
    after_save :force_reindex!

    def force_reindex!
      # in case multiple runs of this block cause the hook
      # to get added multiple times, let's check to make sure
      # we haven't already reindexed for this save
      return if @__reindexed
      Rake["thinking_sphinx:rebuild"].execute
      @__reindexed = true
    end
  end
end

after('@reindexing') do
  class MyModel
    def force_reindex!
      # do nothing; the hook still gets called, but that's ok
    end
  end
end

In /features/integration.feature (or whatever), you'd have

@reindexing
Feature: The whole shebang, altogether

  Scenario: ...
仅一夜美梦 2024-07-28 07:09:02

通过使用数据库清理插件并修改我们的 features/support/env.rb ,我们能够让我们的黄瓜测试成功地与 Think Sphinx 一起工作,如下所示:

# Sets up the Rails environment for Cucumber
ENV["RAILS_ENV"] ||= "cucumber"

...

# http://github.com/bmabey/database_cleaner
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
Before do
  DatabaseCleaner.clean
end

ThinkingSphinx::Configuration.instance.build
ThinkingSphinx::Configuration.instance.controller.start
at_exit do
  ThinkingSphinx::Configuration.instance.controller.stop
end
ThinkingSphinx.deltas_enabled = true
ThinkingSphinx.updates_enabled = true
ThinkingSphinx.suppress_delta_output = true

# Re-generate the index before each Scenario
Before do
  ThinkingSphinx::Configuration.instance.controller.index
end

如您所见,我们还创建了一个“黄瓜”环境和一个单独的数据库(为了同时运行 cucumber 和 specs 而不会发生冲突) - 因此,如果您也想这样做,则需要在 database.yml 和 sphinx.yml 中添加“cucumber:”条目。

We were able to get our cucumber tests to work successfully with thinking sphinx by using a database cleaner plugin and modifying our features/support/env.rb as follows:

# Sets up the Rails environment for Cucumber
ENV["RAILS_ENV"] ||= "cucumber"

...

# http://github.com/bmabey/database_cleaner
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
Before do
  DatabaseCleaner.clean
end

ThinkingSphinx::Configuration.instance.build
ThinkingSphinx::Configuration.instance.controller.start
at_exit do
  ThinkingSphinx::Configuration.instance.controller.stop
end
ThinkingSphinx.deltas_enabled = true
ThinkingSphinx.updates_enabled = true
ThinkingSphinx.suppress_delta_output = true

# Re-generate the index before each Scenario
Before do
  ThinkingSphinx::Configuration.instance.controller.index
end

As you can see, we also created a 'cucumber' environment and a separate database (in order to run cucumber and specs simultaneously without conflicts) - so you will need to add a 'cucumber:' entry to your database.yml and sphinx.yml if you would like to do that as well.

魂牵梦绕锁你心扉 2024-07-28 07:09:02

链接的建议不起作用,因为 Rake 任务在单独的进程中调用索引器,因此在测试事务之外。

我不知道除了关闭测试事务以便 sphinx 索引进程可以看到新的和更新的记录之外还有什么办法可以解决这个问题。 为此,只需在您的 TestCase 中添加行

self.use_transactional_fixtures = false

请记住,您需要在测试结束时管理清除所有数据。

The linked suggestion won't work, because the Rake task invokes the indexer in a seperate process, and so is outside of the test transaction.

I don't know that there's any way around this, other than turning off test transactions so that the sphinx index process can see new and updated records. To do that, in your TestCase, just add the line

self.use_transactional_fixtures = false

Bear in mind that you'll need to manage clearing up any data at the end of your test.

屌丝范 2024-07-28 07:09:02

我不建议您测试不属于您的组件。 这将是一个非常脆弱的测试,因为它将依赖于特定版本的 sphinx 中的特定排名算法,该算法稍后可能会发生变化,从而在未来返回不可预测的结果。

如果您想这样做,我建议您通过 mysql 适配器或 xmlpipe2 选项使用测试数据库运行单独的索引进行测试(xml2pipe 显然可以让您更改数据集,而无需更改 sphinx 文件中的索引选项) 。 这可能需要您一次性单独设置测试数据,删除索引(使用 ruby​​ shell 命令),然后强制重新索引(等待索引文档的总数与已知的数据库记录数量相同) )并针对数据运行测试。

我真的要警告不要像我说的那样测试索引,您可能会发现自己必须处理不断破坏的测试或缓慢的测试运行时间(取决于您索引的数据量)

I would not recommend you test a component that you don't own. It will be a pretty brittle test since it would be dependent on the specific ranking algorithm in that specific version of sphinx that could change later and thus return unpredictable results in the future.

if you want to do this I would however suggest running a separate index for testing either using the test database via the mysql adapter or the xmlpipe2 option (xml2pipe obviously lets you change your data set without having to change the indexing options in your sphinx file). This will probably require that you set up your test data separately all at once, delete the indexes (using ruby shell commands) and then force the reindexing (waiting for the total number of indexed documents to be the same as the known amount of database records) and run your tests against the data.

I would really caution against testing the index like I said you might just find yourself having to deal with a constantly breaking test or slow test runtime (depending on the amount of data you are indexing)

爱的故事 2024-07-28 07:09:02

这可能比它的价值更麻烦,但是您尝试过打开增量索引吗?

this is probably more hassle than what it's worth, but have you tried turning on delta indexes?

木緿 2024-07-28 07:09:02

我尝试了建议的解决方案,但 sphinx 超时并出现以下错误。 我认为在启用事务装置时不可能重新索引 sphinx。

错误:索引“document_core”:sql_query_pre[0]:超出锁定等待超时; 尝试重新启动事务

I tried the suggested solution but sphinx times out with the following error. I don't think it is possible to re-index sphinx while transactional fixtures are enabled.

ERROR: index 'document_core': sql_query_pre[0]: Lock wait timeout exceeded; try restarting transaction

2024-07-28 07:09:02

使用标签来分隔黄瓜思维 sphinx 测试的另一个示例,使用黄瓜标签 此处

Another example of using tags to seperate cucumber thinking sphinx tests using cucumber tags here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文