不时地,我的Rails应用程序的某些规范似乎会随机失败,因为突然英语不再是默认语言,而是德语:
expected: "Project test customer - Project test name (Audit, Access for all, 2015-06-15).pdf"
got: "Project test customer - Project test name (Audit, Zugang für alle, 2015-06-15).pdf"
可以看到,“Access for all”这部分突然变成了“Zugang für alle”。我在谷歌上搜寻了解决方案,似乎发现 I18n.locale
是一个全局对象,所以当在一个 spec 中进行更改时,它会一直保留。
这个问题并不总是发生,但是我可以通过像这样指定种子来复现它:rspec --seed 51012
。因此,真的似乎是某个 spec 在之前(或之后)执行时出现了问题。
我有一个功能规范,测试是否可以更改语言环境,就像这样:
it 'offers contents in german' do
visit root_path(locale: :de)
expect(page).to have_content 'Willkommen'
end
我怀疑这可能是有问题的规范,如果它在早期运行,则会对其他规范产生影响。
我希望通过将规范中的语言设置回默认值来解决这个问题,就像这样:
it 'offers contents in german' do
visit root_path(locale: :de)
expect(page).to have_content 'Willkommen'
I18n.locale = :en
end
没用,这个也不行:
it 'offers contents in german' do
visit root_path(locale: :de)
expect(page).to have_content 'Willkommen'
visit root_path(locale: :en)
end
我现在有些不知所措。我该如何调试这种情况,以便确定问题的根源并修复它(或者至少解决它)?
更新
使用Dave的答案(rspec --bisect
)我找到了问题所在。
# application_controller_spec.rb
describe ApplicationController do
controller(ApplicationController) do
def index
render text: 'Hello World'
end
end
describe 'locale parameter' do
it 'is set to english when not available in the request' do
get :index
expect(I18n.locale).to eq :en
end
it 'can be set through the request' do
get :index, locale: :de
expect(I18n.locale).to eq :de
end
end
end
根据这些规范运行的顺序不同,区域设置会在后续规范中设置为:de
或:en
。
我用BoraMa建议的代码片段进行了修复:
RSpec.configure do |config|
config.after(:each) { I18n.locale = :en }
end
我仍然有点惊讶,RSpec/Rails自己没有自动完成这个操作...
I18n.locale
(例如before(:each) { puts I18n.locale }
),这样你就可以找到问题所在了。此外,我会使用after(:each) { I18n.locale = :en }
来在每个测试后重置语言环境。这两段代码应该放在spec/spec_helper.rb
或spec/rails_helper.rb
中。 - Matouš Borák