gpt4 book ai didi

ruby-on-rails - Elasticsearch 在测试套件中因 HTTP 不堪重负时不同步

转载 作者:数据小太阳 更新时间:2023-10-29 06:41:47 25 4
gpt4 key购买 nike

我有一个带有 Rspec 测试套件的 Rails 应用程序,它有一些依赖于 ElasticSearch 的功能/ Controller 测试。

当我们测试系统周围的“搜索”功能(以及依赖于 ES 的其他功能)时,我们使用真实的 ES,当我们运行单个规范文件时,它在开发环境中完美运行。

当套件在我们的 CI 服务器上运行时,它会变得很奇怪,因为有时 ES 不会足够快地保持同步以使测试成功运行。

我已经搜索了一些在“同步模式”下运行 ES 的方法,或者等到 ES 准备好但到目前为止还没有找到任何东西。我已经看到一些使用 Ruby sleep 的变通方法,但我觉得无法接受。

如何保证 ES 同步运行我的测试?

您如何处理测试套件中的 ES?

这是我的一个测试:

      context "given params page or per_page is set", :elasticsearch do

let(:params) { {query: "Resultados", page: 1, per_page: 2} }

before(:each) do
3.times do |n|
Factory(:company, account: user.account, name: "Resultados Digitais #{n}")
end
sync_companies_index # this is a helper method available to all specs
end

it "paginates the results properly" do
get :index, params
expect(assigns[:companies].length).to eq 2
end

end

这是我的 RSpec 配置 block 和 ES 辅助方法:

RSpec.configure do |config|
config.around :each do |example|
if example.metadata[:elasticsearch]
Lead.tire.index.delete # delete the index for a clean environment
Company.tire.index.delete # delete the index for a clean environment

example.run
else
FakeWeb.register_uri :any, %r(#{Tire::Configuration.url}), body: '{}'
example.run
FakeWeb.clean_registry
end
end
end

def sync_companies_index
sync_index_of Company
end

def sync_leads_index
sync_index_of Lead
end

def sync_index_of(klass)
mapping = MultiJson.encode(klass.tire.mapping_to_hash, :pretty => Tire::Configuration.pretty)
klass.tire.index.create(:mappings => klass.tire.mapping_to_hash, :settings => klass.tire.settings)
"#{klass}::#{klass}Index".constantize.rebuild_index
klass.index.refresh
end

感谢您的帮助!

最佳答案

您的测试很困惑 - 它正在测试分配、分页和(隐式)参数传递。打破它:

参数

let(:tire) { double('tire', :search => :sentinel) }

it 'passes the correct parameters to Companies.tire.search' do
expected_params = ... # Some transformation, if any, of params
Companies.stub(:tire).with(tire)
get :index, params

expect(tire).to have_received(:search).with(expected_params)
end

作业

我们只关心代码取一个值并将它赋值给其他东西,这个值是无关紧要的。

it 'assigns the search results to companies' do
Companies.stub(:tire).with(tire)
get :index, params

expect(assigns[:companies]).to eq :sentinel
end

分页

这是棘手的一点。你不拥有 ES API,所以你不应该 stub 它,但你也不能使用 ES 的实时实例,因为你不能相信它在所有测试场景中都是可靠的,它只是一个 HTTP API 之后全部(这是您遇到的基本问题)。加里·伯恩哈特 (Gary Bernhardt) 在他出色的 screencasts 中解决了这个问题。 - 你只需要伪造 HTTP 调用。使用录像机:

VCR.use_cassette :tire_companies_search do
get :index, params
search_result_length = assigns[:companies].length

expect(search_result_length).to eq 2
end

成功运行一次,然后永远使用盒式磁带(它只是响应的 YAML 文件)。您的测试不再依赖于您无法控制的 API。如果 ES 或您的分页 gem 更新了它们的代码,只需在您知道 API 启动并工作时重新录制磁带即可。如果不让您的测试变得极其脆弱或不删除您不应该添加的东西,真的没有其他选择。

请注意,尽管我们在上面 stub 了 tire - 我们不拥有它 - 但在这些情况下没关系,因为返回值与测试完全无关。

关于ruby-on-rails - Elasticsearch 在测试套件中因 HTTP 不堪重负时不同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20193591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com