continue: ThinkingSphinx & &;回调不更新索引后创建记录
我正在测试与rspec和chrome headless搜索。
对于SQL索引,我使用了这个特性规范+帮助器:https://pastebin.com/9m7WbvN7
用实时代替SQL索引:
ThinkingSphinx::Index.define :review, with: :real_time do
indexes title, sortable: true
indexes body
indexes author.username, as: :author, sortable: true
has author_id, :type => :integer
has created_at, :type => :timestamp
has updated_at, :type => :timestamp
end
在开发模式下,一切正常,但测试开始下降。
我试图编辑sphinx_helper使用手册:https://freelancing-gods.com/thinking-sphinx/v5/testing.html
但我失败了,得到一个错误:
An error occurred in a `before(:suite)` hook.
Failure/Error: ThinkingSphinx::Test.start_with_autostop
Riddle::CommandFailedError:
Sphinx command failed to execute
# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:25:in `call'
# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:7:in `call'
# /gems/riddle-2.4.3/lib/riddle/controller.rb:33:in `index'
# /gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb:13:in `start'
# /gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb:19:in `start_with_autostop'
# ./spec/sphinx_helper.rb:14:in `block (2 levels) in <top (required)>'
添加一个端口并没有改变任何东西。
/config/thinking_sphinx.yml:
test:
mysql41: 9307
如果您通过rake手动运行它,配置文件将被创建,sphinx将成功运行:
bundle exec rake ts:configure RAILS_ENV=test
Generating configuration to /home/vagrant/data/app/config/test.sphinx.conf
bundle exec rake ts:start RAILS_ENV=test
using config file '/home/vagrant/data/app/config/test.sphinx.conf'...
listening on 127.0.0.1:9307
precaching index 'review_core'
precaching index 'user_core'
precached 2 indexes in 0.002 sec
Started searchd successfully (pid: 6532).
test.sphinx.conf的内容与development.sphinx.conf相同,只是路径不同。
test.sphinx.conf, btw,是在尝试运行测试时创建的https://pastebin.com/GavMg5BB
如果添加到/gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb
:
def self.start(options = {})
pp config.controller
output: https://pastebin.com/ta34Ys6k
当运行测试时,没有在log/test.search .log中写入任何内容,因为sphinx没有启动。
呼吁这就是谜语想要运行的::
# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:7
"indexer --config "/home/vagrant/data/app/config/test.sphinx.conf" --all"
如果我尝试手动执行,我得到:ERROR: nothing to do.
万岁,我终于想通了。
是的start_with_autostop
(而不仅仅是它)调用索引,它返回谜语错误。
也不需要调用ThinkingSphinx::Test.index
。
用于包装测试的ThinkingSphinx::Test.run
也不再为我们工作了,因为它调用ThinkingSphinx::Test.start
而不带参数index: false
。
现在我们只需要运行Sphinx并在模型中使用ThinkingSphinx回调,否则您创建的对象将不会被索引,这是有意义的。
由于我们现在对模型有回调,我们必须在使用这些模型的所有测试中保持Sphinx运行,否则我们将得到一个错误:
Error connecting to Sphinx via the MySQL protocol. Can't connect to MySQL server on '127.0.0.1:9307' (111).
所以我们需要Sphinx在整个测试过程中都在后台运行,比如Redis。如果我们在每个规范文件中启动和停止Sphinx,那么我们的测试时间将显著增加。
目前有几个解决方案适合我:
1。添加到RSpec.configure中的rails_helper
# Starting Sphinx before all tests
config.before(:suite) do
ThinkingSphinx::Test.init
ThinkingSphinx::Test.start(index: false)
end
# Stoping ThinkingSphinx after all the tests
config.after(:suite) do
ThinkingSphinx::Test.stop
end
下一个是你的选择:
- 删除DatabaseCleaner和sphinx_helper(一切似乎没有他们与Rails 6工作,也许我使用的手册和使用DatabaseCleaner只是过时)。
- 保留DatabaseCleaner和sphinx_helper,但删除其中的
ThinkingSphinx
调用,sphinx_helper在Sphinx的功能测试中被调用,而不是rails_helper。
2。通过rails_helper:中的Rake任务启动Sphinx
# before RSpec.configure
Rails.application.load_tasks
# inside RSpec.configure
config.before(:suite) do
Rake::Task['ts:configure'].invoke
Rake::Task['ts:start'].invoke
end
config.after(:suite) do
Rake::Task['ts:stop'].invoke
Rake::Task['ts:clear'].invoke
end
下一个选项是:与第1点相同。
3。如果你需要DatabaseCleaner,你可以将它全局地放在RSpec.configure:中的rails_helper中。
config.use_transactional_fixtures = false
# Starting Sphinx before all tests
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
ThinkingSphinx::Test.init
ThinkingSphinx::Test.start(index: false)
end
config.before(:each) do |test|
# fix ActiveRecord::RecordNotFound in JS tests
DatabaseCleaner.strategy = test.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
# Stoping ThinkingSphinx after all the tests.
config.after(:suite) do
ThinkingSphinx::Test.stop
end
sphinx_helper,然后删除它。
在Sphinx的所有功能测试中,您需要删除ThinkingSphinx::Test.run
包装器,以及sphinx: true
和js: true
(除非你明确需要JS)
另外,不要忘记添加回调到索引模型:
ThinkingSphinx::Callbacks.append(
self, :behaviours => [:real_time]
)
您还可以添加在所有测试后删除索引文件夹并停止Sphinx:
config.after(:suite) do
ThinkingSphinx::Test.stop
FileUtils.rm_rf("#{Rails.root}/db/sphinx/test")
end
PS:如果有新的细节我会更新的。