diff --git a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb index 86ec5abd84..742a183268 100644 --- a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb +++ b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb @@ -58,6 +58,7 @@ def example_group_finished(notification) def example_started(notification) example = notification.example attributes = { + 'rspec.example.id' => example.id.to_s, 'rspec.example.location' => example.location.to_s, 'rspec.example.full_description' => example.full_description.to_s, 'rspec.example.described_class' => example.metadata[:described_class].to_s diff --git a/instrumentation/rspec/test/opentelemetry/instrumentation/rspec/formatter_test.rb b/instrumentation/rspec/test/opentelemetry/instrumentation/rspec/formatter_test.rb index bb549a6f22..7d8f2390e4 100644 --- a/instrumentation/rspec/test/opentelemetry/instrumentation/rspec/formatter_test.rb +++ b/instrumentation/rspec/test/opentelemetry/instrumentation/rspec/formatter_test.rb @@ -131,6 +131,10 @@ def run_example(...) _(subject.attributes['rspec.example.location']).must_match %r{\./test/opentelemetry/instrumentation/rspec/formatter_test.rb:\d+} end + it 'has an id attribute' do + _(subject.attributes['rspec.example.id']).must_match %r{\./test/opentelemetry/instrumentation/rspec/formatter_test.rb\[\d+:\d+\]} + end + it 'records when the example passes' do _(subject.attributes['rspec.example.result']).must_equal 'passed' end @@ -346,6 +350,32 @@ def run_example(...) _(subject.attributes['rspec.example.result']).must_equal 'passed' end end + + describe 'dynamic examples with same location' do + it 'have unique example.id attributes' do + spans = run_rspec_with_tracing do + RSpec.describe('dynamic examples') do + [1, 2, 3].each do |num| + example("example #{num}") { expect(num).to be_positive } + end + end + end + + example_spans = spans.select { |span| span.name.start_with?('example ') } + _(example_spans.size).must_equal 3 + + # All examples have the same location (same line in the loop) + locations = example_spans.map { |span| span.attributes['rspec.example.location'] } + _(locations.uniq.size).must_equal 1 + + # But each has a unique id + ids = example_spans.map { |span| span.attributes['rspec.example.id'] } + _(ids.uniq.size).must_equal 3 + ids.each do |id| + _(id).must_match %r{\./test/opentelemetry/instrumentation/rspec/formatter_test.rb\[\d+:\d+\]} + end + end + end end describe 'using a custom tracer provider' do