RSpec timeout configuration inheritance behavior change in version 3.8
0 reputation · 03 Jul 2020, 12:39 UTC
0 reputation · 03 Jul 2020, 12:39 UTC
The RSpec timeout feature introduced in version 3.8 allows a global limit to be set for each example, causing a Timeout::Error when exceeded. Currently this limit does not automatically apply to child example groups; each group or example must declare its own timeout metadata to obtain a different limit.
This lack of inheritance can lead to inconsistent timeout settings across a suite and raises the question of whether a configurable inheritance mode should be provided. The core team has discussed the trade‑offs but has not settled on a default behavior. Should the global timeout be inherited by nested groups unless overridden? Should an explicit configuration flag enable inheritance? How would inherited timeouts interact with explicitly set timeout metadata on a child group or example?
34775 reputation · 03 Jul 2020, 13:37 UTC
In RSpec 3.8, global timeout configurations do not inherit down to nested example groups or individual examples. If a global timeout is defined in the configuration block, it does not automatically apply to child groups; each group or example must explicitly declare its own :timeout metadata to enforce a limit.
The timeout feature allows you to set a limit that triggers a Timeout::Error when exceeded. However, the current implementation treats the global setting and metadata-based settings as distinct. If a child group omits the :timeout metadata, it effectively runs without a timeout, regardless of whether a global limit was defined in spec_helper.rb.
This behavior is a result of how RSpec handles metadata merging. While many configuration options propagate, the timeout mechanism in version 3.8 was designed to rely on explicit metadata triggers. Implementing automatic inheritance would require a change to the internal metadata resolution logic to prioritize a global fallback when specific metadata is absent, a change the core team has noted would likely require an explicit configuration flag to avoid unexpected failures in legacy suites.
To verify this behavior in your environment, you can use the following scoped test case:
spec_helper.rb:
RSpec.configure do |config|
config.timeout = 1
endRSpec.describe "Inheritance Test" do
context "nested group" do
it "should fail if inheritance worked" do
sleep 2 # This will NOT trigger a Timeout::Error
end
end
endtimeout: 0.5 to the it block and re-run; the example will now fail as expected.Until a configurable inheritance flag is introduced, you must explicitly apply :timeout metadata to every example group or example that requires a limit. To ensure consistency across a suite, consider creating a custom metadata tag or a shared context that applies the desired timeout to all included groups.
Diagnostic Detail Needed: Are you utilizing any third-party RSpec plugins for timeout management (such as rspec-timeout) alongside the native 3.8 configuration? This may alter how metadata is merged.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.