Skip to content

Conversation

americodls
Copy link

Adds OpenTelemetry instrumentation for the FactoryBot gem to provide visibility into test data creation patterns during testing.

Subscribes to the factory_bot.run_factory ActiveSupport::Notifications event to capture all factory operations without monkey-patching. Supports FactoryBot 4.0+ and captures all factory strategies (create, build, build_stubbed, attributes_for) including batch operations (create_list, build_list, etc.).

Span naming: FactoryBot.{strategy}({factory_name})
Example: FactoryBot.build(user), FactoryBot.create_list(post)

Span attributes:

  • factory_bot.strategy: Internal strategy name (build, create, stub, attributes_for)
  • factory_bot.factory_name: Name of the factory being used
  • factory_bot.traits: Comma-separated list of traits applied (if any)

@kaylareopelle
Copy link
Contributor

Hi @americodls, thanks for opening this PR. Would you be interested in being a codeowner for this gem? That would involve reviewing PRs and issues related to the factory bot instrumentation. We don't have the codeowner behavior automated in GitHub, but we're currently documenting this in the CODEOWNERS file in the repo.

Adds OpenTelemetry instrumentation for the FactoryBot gem to provide
visibility into test data creation patterns during testing.

Subscribes to the factory_bot.run_factory ActiveSupport::Notifications event
to capture all factory operations without monkey-patching. Supports FactoryBot
4.0+ and captures all factory strategies (create, build, build_stubbed,
attributes_for) including batch operations (create_list, build_list, etc.).

Span naming: FactoryBot.{strategy}({factory_name})
Example: FactoryBot.build(user), FactoryBot.create_list(post)

Span attributes:
- factory_bot.strategy: Internal strategy name (build, create, stub, attributes_for)
- factory_bot.factory_name: Name of the factory being used
- factory_bot.traits: Comma-separated list of traits applied (if any)
@americodls americodls force-pushed the ad/add-factory-bot-instrumentation branch from b21de9a to 48f77b0 Compare October 8, 2025 09:10
@americodls
Copy link
Author

Hi @kaylareopelle! Happy to take it on 🙂
I've just updated the CODEOWNERS file — let me know if anything is needed!

@simi
Copy link
Contributor

simi commented Oct 8, 2025

@americodls would you mind to share more how do you instrument testing also?

span_name = "FactoryBot.#{strategy_symbol}(#{factory_name})"

attrs = {
'factory_bot.strategy' => internal_strategy,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion name this test.data.strategy given it could be used elsewhere and we already have the test namespace?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback!

I checked the OpenTelemetry test semantic conventions and found that the test.* namespace currently only defines attributes for test execution metadata (test cases, suites, and their statuses).

Since test.data isn’t part of the spec yet, using it now could risk conflicts if it’s added later. The current factory_bot.* approach keeps things scoped to this library’s specific domain.

I’d suggest keeping the dedicated namespace for now — we can always generalize to something like test.data.* if similar fixture/factory patterns start appearing across other testing libraries. That way, we’re being intentional rather than speculative about the abstraction.

Of course, I’m open to other perspectives — input from the maintainers would be especially valuable given their broader experience in this space.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So perhaps the following helps defining attributes

When defining an attribute for a narrow use case, think about potential broader use cases. For example, if creating a system-specific attribute, evaluate whether other systems in the same domain might need a similar attribute in the future.

I see the attributes identified as falling into that category as anything generating data needs a strategy etc.

I would even suggest raising a pr to get the attributes/spans added.

'factory_bot.factory_name' => factory_name.to_s
}

attrs['factory_bot.traits'] = traits.join(',') if traits.any?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion name this test.data.traits given it could be used elsewhere and we already have the test namespace?

Comment on lines 29 to 34
attrs = {
'factory_bot.strategy' => internal_strategy,
'factory_bot.factory_name' => factory_name.to_s
}

attrs['factory_bot.traits'] = traits.join(',') if traits.any?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If test.data.* is adopted, I would add a test.data.provider.name attribute.

@americodls
Copy link
Author

@americodls would you mind to share more how do you instrument testing also?

Something like this:

# spec/spec_helper.rb

#...

if ENV["ENABLE_TRACING"]
  require 'opentelemetry/sdk'
  require 'opentelemetry/instrumentation/rspec'

  OpenTelemetry::SDK.configure do |c|
    # ...
    c.use 'OpenTelemetry::Instrumentation::RSpec'
    c.use 'OpenTelemetry::Instrumentation::FactoryBot'
    # ...
  end
end

RSpec.configure do |config|
  #...
  config.after(:suite) do
    OpenTelemetry.tracer_provider.shutdown if ENV["ENABLE_TRACING"]
  end
  #...
end

Copy link
Contributor

@arielvalentin arielvalentin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your submission!

There are a few required changes you will have to make to avoid issues/conflicts with our release tooling.

I will have to reach out for help to other users who are FactoryBot users to help with a review before we merge.

@americodls americodls force-pushed the ad/add-factory-bot-instrumentation branch from da05c9e to 4d0543b Compare October 12, 2025 13:55
Copy link

linux-foundation-easycla bot commented Oct 12, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@americodls americodls force-pushed the ad/add-factory-bot-instrumentation branch 2 times, most recently from 3e4df45 to 30a3ea8 Compare October 12, 2025 14:02
americodls and others added 4 commits October 12, 2025 15:26
Per OpenTelemetry semantic conventions, plural attribute names should
use array values. Changed factory_bot.traits from comma-separated
string to string array.
- Move instrumentation.install to top-level before block
- Remove redundant install calls from nested describe blocks
- Add comprehensive attribute tests for all strategies
- Test empty traits array in all relevant sections
- Ensure all 3 attributes tested: strategy, factory_name, traits
@americodls americodls force-pushed the ad/add-factory-bot-instrumentation branch from 30a3ea8 to 9e42630 Compare October 12, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants