실험 테스트

RSpec를 사용한 실험 테스트

실험을 진행하는 과정에서 RSpec 도구를 사용하고 싶을 수 있습니다. 이는 spec/experiments에 있는 파일에 대해 자동으로 발생하지만, 다른 파일 및 스펙에 대해서는 :experiment 유형을 지정할 수 있습니다:

it "tests experiments nicely", :experiment do
end

Stub 헬퍼

stub_experiments를 사용하여 실험을 대체할 수 있습니다. 각 실험이 해결해야 하는 변형을 값으로 사용하여 실험 이름을 키로 사용하는 해시를 전달하십시오.

# `:example` 및 `:example2`라는 실험이 모두 "활성화"되고 각각 주어진 변형(`:my_variant` 및 `:control`)으로 해결되도록 보장합니다.
stub_experiments(example: :my_variant, example2: :control)

experiment(:example) do |e|
  e.enabled? # => true
  e.assigned.name # => 'my_variant'
end

experiment(:example2) do |e|
  e.enabled? # => true
  e.assigned.name # => 'control'
end

제외, 분할 및 동작 매처

등록된 동작, 제외 및 분할 같은 것들을 매처를 사용하여 테스트할 수도 있습니다.

class ExampleExperiment < ApplicationExperiment
  control { }
  candidate { '_candidate_' }

  exclude { context.actor.first_name == 'Richard' }
  segment(variant: :candidate) { context.actor.username == 'jejacks0n' }
end

excluded = double(username: 'rdiggitty', first_name: 'Richard')
segmented = double(username: 'jejacks0n', first_name: 'Jeremy')

# register_behavior 매처
expect(experiment(:example)).to register_behavior(:control)
expect(experiment(:example)).to register_behavior(:candidate).with('_candidate_')

# exclude 매처
expect(experiment(:example)).to exclude(actor: excluded)
expect(experiment(:example)).not_to exclude(actor: segmented)

# segment 매처
expect(experiment(:example)).to segment(actor: segmented).into(:candidate)
expect(experiment(:example)).not_to segment(actor: excluded)

추적 매처

추적 이벤트는 실험의 주요 측면입니다. 추적 호출이 제대로 되었는지 유연하게 확인할 수 있는 방법을 제공합니다.

이를 인스턴스 수준 또는 “모든 인스턴스” 수준에서 수행할 수 있습니다:

subject = experiment(:example)

expect(subject).to track(:my_event)

subject.track(:my_event)

on_next_instance 체인 메서드를 사용하여 다음 실험 인스턴스에서 발생하도록 지정할 수 있습니다. 이는 아래 게시된 experiment(:example).track를 호출하는 경우 도움이 됩니다:

expect(experiment(:example)).to track(:my_event).on_next_instance

experiment(:example).track(:my_event)

track 매처에 연결할 수 있는 메서드의 예시입니다:

expect(experiment(:example)).to track(:my_event, value: 1, property: '_property_')
  .on_next_instance
  .with_context(foo: :bar)
  .for(:variant_name)

experiment(:example, :variant_name, foo: :bar).track(:my_event, value: 1, property: '_property_')

Jest로 테스트

Stub 헬퍼

spec/frontend/__helpers__/experimentation_helper.js에 정의된 stubExperiments 헬퍼를 사용하여 실험을 대체할 수 있습니다.

import { stubExperiments } from 'helpers/experimentation_helper';
import { getExperimentData } from '~/experimentation/utils';

describe('when my_experiment is enabled', () => {
  beforeEach(() => {
    stubExperiments({ my_experiment: 'candidate' });
  });

  it('sets the correct data', () => {
    expect(getExperimentData('my_experiment')).toEqual({ experiment: 'my_experiment', variant: 'candidate' });
  });
});

참고: 이 Jest 스펙에서의 스텁 항목화 방법은 테스트 종료 후 자동으로 스텁을 해제하지 않습니다. 스텁된 실험을 window.gl의 모든 다른 전역 데이터와 병합합니다. 테스트 이후에 스텁된 실험을 제거해야 하거나 테스트 전에 깨끗한 글로벌 객체를 보장해야 하는 경우, 전역 객체를 직접 관리해야 합니다:

describe('전역 상태에 관심 있는 테스트', () => {
  const originalObjects = [];

  beforeEach(() => {
    // 현재까지는 window.gon 및 window.gl을 모두 사용하고 있으므로, 이러한 객체를 originalObjects에 추가합니다.
    originalObjects.push(window.gon, window.gl);
  });

  afterEach(() => {
    [window.gon, window.gl] = originalObjects;
  });

  it('새로운 글로벌 상태에서 실험을 스텁', () => {
    stubExperiment({ my_experiment: 'candidate' });
    // ...
  });
});