실험 테스트

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 도우미

stubExperiments 도우미를 사용하여 spec/frontend/__helpers__/experimentation_helper.js에 정의된 실험을 스텁할 수 있습니다.

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.push(window.gon, window.gl);
  });

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

  it('새로운 전역 상태에서 실험 스텁하기', () => {
    stubExperiment({ my_experiment: 'candidate' });
    // ...
  });
})