Repository navigation
A partial rerun replaces a shared test id with only what it ran #1321
Description
Since #1316, a later run replaces a context's lines when it records the same id again, so a rerun test's lines stay current. That assumes one id stands for one thing that either runs in full or not at all. Two kinds of id break that assumption. When a partial rerun (rspec --only-failures, rspec spec/x_spec.rb:6, simplecov affected --run) runs only part of what an id stands for, the id is recorded with only that part. Lines that only the rest ran then map to no test, and simplecov affected selects nothing for a change to them and exits 0.
Examples that share a path:line
track_tests identifies an RSpec example by its path:line, but examples defined in a loop share one:
RSpec.describe Widget do
%w[a b c].each do |name|
it("handles #{name}") { expect(Widget.new(name)).to be_valid }
end
endAll three examples are recorded as spec/widget_spec.rb:3. Rerunning one of them records that id with its lines alone.
This is common. In hashie's suite, 280 of 1072 examples share their path:line with another example, in 95 places (measured in #1319 (comment)).
A spec file's bare id
Since #1320, a spec file's bare id (spec/x_spec.rb) holds its groups' before(:all) hooks as well as its loading:
RSpec.describe "First" do
before(:all) { Setup.one }
it("a") { expect(1).to eq(1) } # spec/x_spec.rb:6
end
RSpec.describe "Second" do
before(:all) { Setup.two }
it("b") { expect(1).to eq(1) }
endA full run credits both Setup.one and Setup.two to spec/x_spec.rb. Rerunning only rspec spec/x_spec.rb:6 runs just the first group's hook, so spec/x_spec.rb is recorded with Setup.one alone, and simplecov tests then reports no recorded test covering Setup.two. Before #1320 the bare id held only the file's loading, which every rerun of the file repeats in full. (Before #1320 this case was worse: a full run already left Setup.one to no test and credited Setup.two to spec/x_spec.rb:6, and the same rerun lost both.)
Options
- Use
example.idfor every RSpec example. Credit shared examples to the spec file that includes them #1319 already does this for shared examples (spec/a_spec.rb[1:2:1]), and everything that reads ids accepts that form throughSimpleCov::TEST_ID_TAIL. Every example id becomes unique, which fixes the first case but not the bare id. Every RSpec id changes, ids likespec/a_spec.rb[1:1:11:4]are harder to read in the HTML report and--explainthanspec/a_spec.rb:42, and a map recorded before the change would need to be recorded again. - Use
example.idonly for examples whosepath:lineanother example shares. This keeps most ids readable but has the same reach as the option above. It needs every example's location before the first one runs, and an id would change when a second example appears at the same line. - Merge an id's lines on a rerun instead of replacing them. This fixes both cases and keeps ids readable. The cost is the one Ideas for improving test selection in
simplecov affected#1316 replaced to avoid: lines a test no longer runs stay credited to it, soaffectedcan select extra tests, never fewer, and nothing short of recording the map again from scratch clears them. - Combine them: unique example ids by either of the first two options, with merging only for bare ids. A bare id's loading is the same on every rerun, so merging it only keeps setup lines that a partial rerun did not repeat.
Activity
[-]Examples defined in a loop share one test id and lose lines on a partial rerun[/-][+]A partial rerun replaces a shared test id with only what it ran[/+]Keep the lines a partial rerun did not repeat