Commit 0e5e5a07 authored by Nicolas Dular's avatar Nicolas Dular

Introduce snowplow event test helper

By calling the original method, we can make sure that the types
are correct. Snowplow is using a type checking gem that would
otherwise throw an exception in runtime. This is something we want
to catch in tests.

Replace the AsyncEmitter with Emitter. We want to avoid
AsyncEmitter because it does some work in a separate thread, and
we want any failures to occur in the same thread as the test.
parent 1a9d624a
......@@ -524,6 +524,48 @@ for modifications. If you have no other choice, an `around` block similar to the
example for global variables, above, can be used, but this should be avoided if
at all possible.
#### Test Snowplow events
CAUTION: **Warning:**
Snowplow performs **runtime type checks** by using the [contracts gem](https://rubygems.org/gems/contracts).
Since Snowplow is **by default disabled in tests and development**, it can be hard to
**catch exceptions** when mocking `Gitlab::Tracking`.
To catch runtime errors due to type checks, you can enable Snowplow in tests by marking the spec with
`:snowplow` and use the `expect_snowplow_event` helper which will check for
calls to `Gitlab::Tracking#event`.
```ruby
describe '#show', :snowplow do
it 'tracks snowplow events' do
get :show
expect_snowplow_event(
category: 'Experiment',
action: 'start',
)
expect_snowplow_event(
category: 'Experiment',
action: 'sent',
property: 'property',
label: 'label'
)
end
end
```
When you want to ensure that no event got called, you can use `expect_no_snowplow_event`.
```ruby
describe '#show', :snowplow do
it 'does not track any snowplow events' do
get :show
expect_no_snowplow_event
end
end
```
### Table-based / Parameterized tests
This style of testing is used to exercise one piece of code with a comprehensive
......
......@@ -56,12 +56,19 @@ module Gitlab
def snowplow
@snowplow ||= SnowplowTracker::Tracker.new(
SnowplowTracker::AsyncEmitter.new(Gitlab::CurrentSettings.snowplow_collector_hostname, protocol: 'https'),
emitter,
SnowplowTracker::Subject.new,
SNOWPLOW_NAMESPACE,
Gitlab::CurrentSettings.snowplow_app_id
)
end
def emitter
SnowplowTracker::AsyncEmitter.new(
Gitlab::CurrentSettings.snowplow_collector_hostname,
protocol: 'https'
)
end
end
end
end
......@@ -115,6 +115,7 @@ RSpec.configure do |config|
config.include StubExperiments
config.include StubGitlabCalls
config.include StubGitlabData
config.include SnowplowHelpers
config.include NextFoundInstanceOf
config.include NextInstanceOf
config.include TestEnv
......
# frozen_string_literal: true
module SnowplowHelpers
# Asserts call for one snowplow event from `Gitlab::Tracking#event`.
#
# @param [Hash]
#
# Examples:
#
# describe '#show', :snowplow do
# it 'tracks snowplow events' do
# get :show
#
# expect_snowplow_event(category: 'Experiment', action: 'start')
# end
# end
#
# describe '#create', :snowplow do
# it 'tracks snowplow events' do
# post :create
#
# expect_snowplow_event(
# category: 'Experiment',
# action: 'created',
# )
# expect_snowplow_event(
# category: 'Experiment',
# action: 'accepted',
# property: 'property',
# label: 'label'
# )
# end
# end
def expect_snowplow_event(category:, action:, **kwargs)
expect(Gitlab::Tracking).to have_received(:event)
.with(category, action, **kwargs)
end
# Asserts that no call to `Gitlab::Tracking#event` was made.
#
# Example:
#
# describe '#show', :snowplow do
# it 'does not track any snowplow events' do
# get :show
#
# expect_no_snowplow_event
# end
# end
def expect_no_snowplow_event
expect(Gitlab::Tracking).not_to have_received(:event)
end
end
# frozen_string_literal: true
RSpec.configure do |config|
config.before(:each, :snowplow) do
# Using a high buffer size to not cause early flushes
buffer_size = 100
# WebMock is set up to allow requests to `localhost`
host = 'localhost'
allow(Gitlab::Tracking)
.to receive(:emitter)
.and_return(SnowplowTracker::Emitter.new(host, buffer_size: buffer_size))
stub_application_setting(snowplow_enabled: true)
allow(Gitlab::Tracking).to receive(:event).and_call_original
end
config.after(:each, :snowplow) do
Gitlab::Tracking.send(:snowplow).flush
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment